/// <summary> /// Constructs a <c>AnnualTimeZoneRule</c> with the name, the GMT /// offset of its standard time, the amount of daylight saving offset /// adjustment, the annual start time rule and the start/until years. /// </summary> /// /// <param name="name">The time zone name.</param> /// <param name="rawOffset">The GMT offset of its standard time in milliseconds.</param> /// <param name="dstSavings">The amount of daylight saving offset adjustment inmilliseconds. If this ia a rule for standard time, the valueof this argument is 0.</param> /// <param name="dateTimeRule_0">The start date/time rule repeated annually.</param> /// <param name="startYear_1">The first year when this rule takes effect.</param> /// <param name="endYear_2">The last year when this rule takes effect. If this rule iseffective forever in future, specify MAX_YEAR.</param> /// @draft ICU 3.8 /// @provisional This API might change or be removed in a future release. public AnnualTimeZoneRule(String name, int rawOffset, int dstSavings, DateTimeRule dateTimeRule_0, int startYear_1, int endYear_2) : base(name, rawOffset, dstSavings) { this.dateTimeRule = dateTimeRule_0; this.startYear = startYear_1; this.endYear = (endYear_2 > MAX_YEAR) ? MAX_YEAR : endYear_2; }
/// <summary> /// Gets the array of <c>TimeZoneRule</c> which represents the rule of /// this time zone object near the specified date. Some applications are not /// capable to handle historic time zone rule changes. Also some applications /// can only handle certain type of rule definitions. This method returns /// either a single <c>InitialTimeZoneRule</c> if this time zone does /// not have any daylight saving time within 1 year from the specified time, /// or a pair of <c>AnnualTimeZoneRule</c> whose rule type is /// <c>DateTimeRule.DOW</c> for date and /// <c>DateTimeRule.WALL_TIME</c> for time with a single /// <c>InitialTimeZoneRule</c> representing the initial time, when this /// time zone observes daylight saving time near the specified date. Thus, /// the result may be only valid for dates around the specified date. /// </summary> /// /// <param name="date">The date to be used for <c>TimeZoneRule</c> extraction.</param> /// <returns>The array of <c>TimeZoneRule</c>, either a single /// <c>InitialTimeZoneRule</c> object, or a pair of /// <c>AnnualTimeZoneRule</c> with a single /// <c>InitialTimeZoneRule</c>. The first element in the array /// is always a <c>InitialTimeZoneRule</c>.</returns> /// @draft ICU 3.8 /// @provisional This API might change or be removed in a future release. public TimeZoneRule[] GetSimpleTimeZoneRulesNear(long date) { AnnualTimeZoneRule[] annualRules = null; TimeZoneRule initialRule = null; // Get the next transition TimeZoneTransition tr = GetNextTransition(date, false); if (tr != null) { String initialName = tr.GetFrom().GetName(); int initialRaw = tr.GetFrom().GetRawOffset(); int initialDst = tr.GetFrom().GetDSTSavings(); // Check if the next transition is either DST->STD or STD->DST and // within roughly 1 year from the specified date long nextTransitionTime = tr.GetTime(); if (((tr.GetFrom().GetDSTSavings() == 0 && tr.GetTo() .GetDSTSavings() != 0) || (tr.GetFrom().GetDSTSavings() != 0 && tr .GetTo().GetDSTSavings() == 0)) && date + MILLIS_PER_YEAR > nextTransitionTime) { // Get the next next transition annualRules = new AnnualTimeZoneRule[2]; int[] dtfields = IBM.ICU.Impl.Grego.TimeToFields( nextTransitionTime + tr.GetFrom().GetRawOffset() + tr.GetFrom().GetDSTSavings(), null); int weekInMonth = IBM.ICU.Impl.Grego.GetDayOfWeekInMonth(dtfields[0], dtfields[1], dtfields[2]); // Create DOW rule DateTimeRule dtr = new DateTimeRule(dtfields[1], weekInMonth, dtfields[3], dtfields[5], IBM.ICU.Util.DateTimeRule.WALL_TIME); annualRules[0] = new AnnualTimeZoneRule(tr.GetTo().GetName(), tr.GetTo().GetRawOffset(), tr.GetTo().GetDSTSavings(), dtr, dtfields[0], IBM.ICU.Util.AnnualTimeZoneRule.MAX_YEAR); tr = GetNextTransition(nextTransitionTime, false); AnnualTimeZoneRule secondRule = null; if (tr != null) { // Check if the next next transition is either DST->STD or // STD->DST // and within roughly 1 year from the next transition if (((tr.GetFrom().GetDSTSavings() == 0 && tr.GetTo() .GetDSTSavings() != 0) || (tr.GetFrom() .GetDSTSavings() != 0 && tr.GetTo().GetDSTSavings() == 0)) && nextTransitionTime + MILLIS_PER_YEAR > tr .GetTime()) { // Generate another DOW rule dtfields = IBM.ICU.Impl.Grego.TimeToFields(tr.GetTime() + tr.GetFrom().GetRawOffset() + tr.GetFrom().GetDSTSavings(), dtfields); weekInMonth = IBM.ICU.Impl.Grego.GetDayOfWeekInMonth(dtfields[0], dtfields[1], dtfields[2]); dtr = new DateTimeRule(dtfields[1], weekInMonth, dtfields[3], dtfields[5], IBM.ICU.Util.DateTimeRule.WALL_TIME); secondRule = new AnnualTimeZoneRule(tr.GetTo() .GetName(), tr.GetTo().GetRawOffset(), tr .GetTo().GetDSTSavings(), dtr, dtfields[0] - 1, IBM.ICU.Util.AnnualTimeZoneRule.MAX_YEAR); // Make sure this rule can be applied to the specified // date DateTime d = secondRule.GetPreviousStart(date, tr.GetFrom() .GetRawOffset(), tr.GetFrom().GetDSTSavings(), true); if (d != null && (d.Ticks / 10000) <= date && initialRaw == tr.GetTo().GetRawOffset() && initialDst == tr.GetTo().GetDSTSavings()) { // We can use this rule as the second transition // rule annualRules[1] = secondRule; } } } if (annualRules[1] == null) { // Try previous transition tr = GetPreviousTransition(date, true); if (tr != null) { // Check if the previous transition is either DST->STD // or STD->DST. // The actual transition time does not matter here. if ((tr.GetFrom().GetDSTSavings() == 0 && tr.GetTo() .GetDSTSavings() != 0) || (tr.GetFrom().GetDSTSavings() != 0 && tr .GetTo().GetDSTSavings() == 0)) { // Generate another DOW rule dtfields = IBM.ICU.Impl.Grego.TimeToFields(tr.GetTime() + tr.GetFrom().GetRawOffset() + tr.GetFrom().GetDSTSavings(), dtfields); weekInMonth = IBM.ICU.Impl.Grego.GetDayOfWeekInMonth( dtfields[0], dtfields[1], dtfields[2]); dtr = new DateTimeRule(dtfields[1], weekInMonth, dtfields[3], dtfields[5], IBM.ICU.Util.DateTimeRule.WALL_TIME); secondRule = new AnnualTimeZoneRule(tr.GetTo() .GetName(), tr.GetTo().GetRawOffset(), tr .GetTo().GetDSTSavings(), dtr, annualRules[0].GetStartYear() - 1, IBM.ICU.Util.AnnualTimeZoneRule.MAX_YEAR); // Check if this rule start after the first rule // after the specified date DateTime d_0 = secondRule.GetNextStart(date, tr.GetFrom() .GetRawOffset(), tr.GetFrom() .GetDSTSavings(), false); if ((d_0.Ticks / 10000) > nextTransitionTime) { // We can use this rule as the second transition // rule annualRules[1] = secondRule; } } } } if (annualRules[1] == null) { // Cannot generate a good pair of AnnualTimeZoneRule annualRules = null; } else { // The initial rule should represent the rule before the // previous transition initialName = annualRules[0].GetName(); initialRaw = annualRules[0].GetRawOffset(); initialDst = annualRules[0].GetDSTSavings(); } } initialRule = new InitialTimeZoneRule(initialName, initialRaw, initialDst); } else { // Try the previous one tr = GetPreviousTransition(date, true); if (tr != null) { initialRule = new InitialTimeZoneRule(tr.GetTo().GetName(), tr .GetTo().GetRawOffset(), tr.GetTo().GetDSTSavings()); } else { // No transitions in the past. Just use the current offsets int[] offsets = new int[2]; GetOffset(date, false, offsets); initialRule = new InitialTimeZoneRule(GetID(), offsets[0], offsets[1]); } } TimeZoneRule[] result = null; if (annualRules == null) { result = new TimeZoneRule[1]; result[0] = initialRule; } else { result = new TimeZoneRule[3]; result[0] = initialRule; result[1] = annualRules[0]; result[2] = annualRules[1]; } return(result); }