1 /* GENERATED SOURCE. DO NOT MODIFY. */ 2 // © 2016 and later: Unicode, Inc. and others. 3 // License & terms of use: http://www.unicode.org/copyright.html#License 4 /* 5 ******************************************************************************* 6 * Copyright (C) 2007-2010, International Business Machines Corporation and * 7 * others. All Rights Reserved. * 8 ******************************************************************************* 9 */ 10 package ohos.global.icu.util; 11 import java.util.Date; 12 13 import ohos.global.icu.impl.Grego; 14 15 16 /** 17 * <code>AnnualTimeZoneRule</code> is a class used for representing a time zone 18 * rule which takes effect annually. Years used in this class are 19 * all Gregorian calendar years. 20 * 21 * @hide exposed on OHOS 22 */ 23 public class AnnualTimeZoneRule extends TimeZoneRule { 24 25 private static final long serialVersionUID = -8870666707791230688L; 26 27 /** 28 * The constant representing the maximum year used for designating a rule is permanent. 29 */ 30 public static final int MAX_YEAR = Integer.MAX_VALUE; 31 32 private final DateTimeRule dateTimeRule; 33 private final int startYear; 34 private final int endYear; 35 36 /** 37 * Constructs a <code>AnnualTimeZoneRule</code> with the name, the GMT offset of its 38 * standard time, the amount of daylight saving offset adjustment, 39 * the annual start time rule and the start/until years. 40 * 41 * @param name The time zone name. 42 * @param rawOffset The GMT offset of its standard time in milliseconds. 43 * @param dstSavings The amount of daylight saving offset adjustment in 44 * milliseconds. If this ia a rule for standard time, 45 * the value of this argument is 0. 46 * @param dateTimeRule The start date/time rule repeated annually. 47 * @param startYear The first year when this rule takes effect. 48 * @param endYear The last year when this rule takes effect. If this 49 * rule is effective forever in future, specify MAX_YEAR. 50 */ AnnualTimeZoneRule(String name, int rawOffset, int dstSavings, DateTimeRule dateTimeRule, int startYear, int endYear)51 public AnnualTimeZoneRule(String name, int rawOffset, int dstSavings, 52 DateTimeRule dateTimeRule, int startYear, int endYear) { 53 super(name, rawOffset, dstSavings); 54 this.dateTimeRule = dateTimeRule; 55 this.startYear = startYear; 56 this.endYear = endYear; 57 } 58 59 /** 60 * Gets the start date/time rule associated used by this rule. 61 * 62 * @return An <code>AnnualDateTimeRule</code> which represents the start date/time 63 * rule used by this time zone rule. 64 */ getRule()65 public DateTimeRule getRule() { 66 return dateTimeRule; 67 } 68 69 /** 70 * Gets the first year when this rule takes effect. 71 * 72 * @return The start year of this rule. The year is in Gregorian calendar 73 * with 0 == 1 BCE, -1 == 2 BCE, etc. 74 */ getStartYear()75 public int getStartYear() { 76 return startYear; 77 } 78 79 /** 80 * Gets the end year when this rule takes effect. 81 * 82 * @return The end year of this rule (inclusive). The year is in Gregorian calendar 83 * with 0 == 1 BCE, -1 == 2 BCE, etc. 84 */ getEndYear()85 public int getEndYear() { 86 return endYear; 87 } 88 89 /** 90 * Gets the time when this rule takes effect in the given year. 91 * 92 * @param year The Gregorian year, with 0 == 1 BCE, -1 == 2 BCE, etc. 93 * @param prevRawOffset The standard time offset from UTC before this rule 94 * takes effect in milliseconds. 95 * @param prevDSTSavings The amount of daylight saving offset from the 96 * standard time. 97 * 98 * @return The time when this rule takes effect in the year, or 99 * null if this rule is not applicable in the year. 100 */ getStartInYear(int year, int prevRawOffset, int prevDSTSavings)101 public Date getStartInYear(int year, int prevRawOffset, int prevDSTSavings) { 102 if (year < startYear || year > endYear) { 103 return null; 104 } 105 106 long ruleDay; 107 int type = dateTimeRule.getDateRuleType(); 108 109 if (type == DateTimeRule.DOM) { 110 ruleDay = Grego.fieldsToDay(year, dateTimeRule.getRuleMonth(), dateTimeRule.getRuleDayOfMonth()); 111 } else { 112 boolean after = true; 113 if (type == DateTimeRule.DOW) { 114 int weeks = dateTimeRule.getRuleWeekInMonth(); 115 if (weeks > 0) { 116 ruleDay = Grego.fieldsToDay(year, dateTimeRule.getRuleMonth(), 1); 117 ruleDay += 7 * (weeks - 1); 118 } else { 119 after = false; 120 ruleDay = Grego.fieldsToDay(year, dateTimeRule.getRuleMonth(), 121 Grego.monthLength(year, dateTimeRule.getRuleMonth())); 122 ruleDay += 7 * (weeks + 1); 123 } 124 } else { 125 int month = dateTimeRule.getRuleMonth(); 126 int dom = dateTimeRule.getRuleDayOfMonth(); 127 if (type == DateTimeRule.DOW_LEQ_DOM) { 128 after = false; 129 // Handle Feb <=29 130 if (month == Calendar.FEBRUARY && dom == 29 && !Grego.isLeapYear(year)) { 131 dom--; 132 } 133 } 134 ruleDay = Grego.fieldsToDay(year, month, dom); 135 } 136 137 int dow = Grego.dayOfWeek(ruleDay); 138 int delta = dateTimeRule.getRuleDayOfWeek() - dow; 139 if (after) { 140 delta = delta < 0 ? delta + 7 : delta; 141 } else { 142 delta = delta > 0 ? delta - 7 : delta; 143 } 144 ruleDay += delta; 145 } 146 147 long ruleTime = ruleDay * Grego.MILLIS_PER_DAY + dateTimeRule.getRuleMillisInDay(); 148 if (dateTimeRule.getTimeRuleType() != DateTimeRule.UTC_TIME) { 149 ruleTime -= prevRawOffset; 150 } 151 if (dateTimeRule.getTimeRuleType() == DateTimeRule.WALL_TIME) { 152 ruleTime -= prevDSTSavings; 153 } 154 return new Date(ruleTime); 155 } 156 157 /** 158 * {@inheritDoc} 159 */ 160 @Override getFirstStart(int prevRawOffset, int prevDSTSavings)161 public Date getFirstStart(int prevRawOffset, int prevDSTSavings) { 162 return getStartInYear(startYear, prevRawOffset, prevDSTSavings); 163 } 164 165 /** 166 * {@inheritDoc} 167 */ 168 @Override getFinalStart(int prevRawOffset, int prevDSTSavings)169 public Date getFinalStart(int prevRawOffset, int prevDSTSavings) { 170 if (endYear == MAX_YEAR) { 171 return null; 172 } 173 return getStartInYear(endYear, prevRawOffset, prevDSTSavings); 174 } 175 176 /** 177 * {@inheritDoc} 178 */ 179 @Override getNextStart(long base, int prevRawOffset, int prevDSTSavings, boolean inclusive)180 public Date getNextStart(long base, int prevRawOffset, int prevDSTSavings, boolean inclusive) { 181 int[] fields = Grego.timeToFields(base, null); 182 int year = fields[0]; 183 if (year < startYear) { 184 return getFirstStart(prevRawOffset, prevDSTSavings); 185 } 186 Date d = getStartInYear(year, prevRawOffset, prevDSTSavings); 187 if (d != null && (d.getTime() < base || (!inclusive && (d.getTime() == base)))) { 188 d = getStartInYear(year + 1, prevRawOffset, prevDSTSavings); 189 } 190 return d; 191 } 192 193 /** 194 * {@inheritDoc} 195 */ 196 @Override getPreviousStart(long base, int prevRawOffset, int prevDSTSavings, boolean inclusive)197 public Date getPreviousStart(long base, int prevRawOffset, int prevDSTSavings, boolean inclusive) { 198 int[] fields = Grego.timeToFields(base, null); 199 int year = fields[0]; 200 if (year > endYear) { 201 return getFinalStart(prevRawOffset, prevDSTSavings); 202 } 203 Date d = getStartInYear(year, prevRawOffset, prevDSTSavings); 204 if (d != null && (d.getTime() > base || (!inclusive && (d.getTime() == base)))) { 205 d = getStartInYear(year - 1, prevRawOffset, prevDSTSavings); 206 } 207 return d; 208 } 209 210 /** 211 * {@inheritDoc} 212 */ 213 @Override isEquivalentTo(TimeZoneRule other)214 public boolean isEquivalentTo(TimeZoneRule other) { 215 if (!(other instanceof AnnualTimeZoneRule)) { 216 return false; 217 } 218 AnnualTimeZoneRule otherRule = (AnnualTimeZoneRule)other; 219 if (startYear == otherRule.startYear 220 && endYear == otherRule.endYear 221 && dateTimeRule.equals(otherRule.dateTimeRule)) { 222 return super.isEquivalentTo(other); 223 } 224 return false; 225 } 226 227 /** 228 * {@inheritDoc}<br><br> 229 * Note: This method in <code>AnnualTimeZoneRule</code> always returns true. 230 */ 231 @Override isTransitionRule()232 public boolean isTransitionRule() { 233 return true; 234 } 235 236 /** 237 * Returns a <code>String</code> representation of this <code>AnnualTimeZoneRule</code> object. 238 * This method is used for debugging purpose only. The string representation can be changed 239 * in future version of ICU without any notice. 240 */ 241 @Override toString()242 public String toString() { 243 StringBuilder buf = new StringBuilder(); 244 buf.append(super.toString()); 245 buf.append(", rule={" + dateTimeRule + "}"); 246 buf.append(", startYear=" + startYear); 247 buf.append(", endYear="); 248 if (endYear == MAX_YEAR) { 249 buf.append("max"); 250 } else { 251 buf.append(endYear); 252 } 253 return buf.toString(); 254 } 255 } 256