Пример #1
0
 /// <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;
 }
Пример #2
0
        /// <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);
        }