Home | History | Annotate | Download | only in unicode
      1 //  2016 and later: Unicode, Inc. and others.
      2 // License & terms of use: http://www.unicode.org/copyright.html
      3 /*
      4  ********************************************************************************
      5  * Copyright (C) 1997-2013, International Business Machines                     *
      6  * Corporation and others. All Rights Reserved.                                 *
      7  ********************************************************************************
      8  *
      9  * File SIMPLETZ.H
     10  *
     11  * Modification History:
     12  *
     13  *   Date        Name        Description
     14  *   04/21/97    aliu        Overhauled header.
     15  *   08/10/98    stephen     JDK 1.2 sync
     16  *                           Added setStartRule() / setEndRule() overloads
     17  *                           Added hasSameRules()
     18  *   09/02/98    stephen     Added getOffset(monthLen)
     19  *                           Changed getOffset() to take UErrorCode
     20  *   07/09/99    stephen     Removed millisPerHour (unused, for HP compiler)
     21  *   12/02/99    aliu        Added TimeMode and constructor and setStart/EndRule
     22  *                           methods that take TimeMode. Added to docs.
     23  ********************************************************************************
     24  */
     25 
     26 #ifndef SIMPLETZ_H
     27 #define SIMPLETZ_H
     28 
     29 #include "unicode/utypes.h"
     30 
     31 /**
     32  * \file
     33  * \brief C++ API: SimpleTimeZone is a concrete subclass of TimeZone.
     34  */
     35 
     36 #if !UCONFIG_NO_FORMATTING
     37 
     38 #include "unicode/basictz.h"
     39 
     40 U_NAMESPACE_BEGIN
     41 
     42 // forward declaration
     43 class InitialTimeZoneRule;
     44 class TimeZoneTransition;
     45 class AnnualTimeZoneRule;
     46 
     47 /**
     48  * <code>SimpleTimeZone</code> is a concrete subclass of <code>TimeZone</code>
     49  * that represents a time zone for use with a Gregorian calendar. This
     50  * class does not handle historical changes.
     51  * <P>
     52  * When specifying daylight-savings-time begin and end dates, use a negative value for
     53  * <code>dayOfWeekInMonth</code> to indicate that <code>SimpleTimeZone</code> should
     54  * count from the end of the month backwards. For example, if Daylight Savings
     55  * Time starts or ends at the last Sunday a month, use <code>dayOfWeekInMonth = -1</code>
     56  * along with <code>dayOfWeek = UCAL_SUNDAY</code> to specify the rule.
     57  *
     58  * @see      Calendar
     59  * @see      GregorianCalendar
     60  * @see      TimeZone
     61  * @author   D. Goldsmith, Mark Davis, Chen-Lieh Huang, Alan Liu
     62  */
     63 class U_I18N_API SimpleTimeZone: public BasicTimeZone {
     64 public:
     65 
     66     /**
     67      * TimeMode is used, together with a millisecond offset after
     68      * midnight, to specify a rule transition time.  Most rules
     69      * transition at a local wall time, that is, according to the
     70      * current time in effect, either standard, or DST.  However, some
     71      * rules transition at local standard time, and some at a specific
     72      * UTC time.  Although it might seem that all times could be
     73      * converted to wall time, thus eliminating the need for this
     74      * parameter, this is not the case.
     75      * @stable ICU 2.0
     76      */
     77     enum TimeMode {
     78         WALL_TIME = 0,
     79         STANDARD_TIME,
     80         UTC_TIME
     81     };
     82 
     83     /**
     84      * Copy constructor
     85      * @param source the object to be copied.
     86      * @stable ICU 2.0
     87      */
     88     SimpleTimeZone(const SimpleTimeZone& source);
     89 
     90     /**
     91      * Default assignment operator
     92      * @param right    the object to be copied.
     93      * @stable ICU 2.0
     94      */
     95     SimpleTimeZone& operator=(const SimpleTimeZone& right);
     96 
     97     /**
     98      * Destructor
     99      * @stable ICU 2.0
    100      */
    101     virtual ~SimpleTimeZone();
    102 
    103     /**
    104      * Returns true if the two TimeZone objects are equal; that is, they have
    105      * the same ID, raw GMT offset, and DST rules.
    106      *
    107      * @param that  The SimpleTimeZone object to be compared with.
    108      * @return      True if the given time zone is equal to this time zone; false
    109      *              otherwise.
    110      * @stable ICU 2.0
    111      */
    112     virtual UBool operator==(const TimeZone& that) const;
    113 
    114     /**
    115      * Constructs a SimpleTimeZone with the given raw GMT offset and time zone ID,
    116      * and which doesn't observe daylight savings time.  Normally you should use
    117      * TimeZone::createInstance() to create a TimeZone instead of creating a
    118      * SimpleTimeZone directly with this constructor.
    119      *
    120      * @param rawOffsetGMT  The given base time zone offset to GMT.
    121      * @param ID         The timezone ID which is obtained from
    122      *                   TimeZone.getAvailableIDs.
    123      * @stable ICU 2.0
    124      */
    125     SimpleTimeZone(int32_t rawOffsetGMT, const UnicodeString& ID);
    126 
    127     /**
    128      * Construct a SimpleTimeZone with the given raw GMT offset, time zone ID,
    129      * and times to start and end daylight savings time. To create a TimeZone that
    130      * doesn't observe daylight savings time, don't use this constructor; use
    131      * SimpleTimeZone(rawOffset, ID) instead. Normally, you should use
    132      * TimeZone.createInstance() to create a TimeZone instead of creating a
    133      * SimpleTimeZone directly with this constructor.
    134      * <P>
    135      * Various types of daylight-savings time rules can be specfied by using different
    136      * values for startDay and startDayOfWeek and endDay and endDayOfWeek.  For a
    137      * complete explanation of how these parameters work, see the documentation for
    138      * setStartRule().
    139      *
    140      * @param rawOffsetGMT      The new SimpleTimeZone's raw GMT offset
    141      * @param ID                The new SimpleTimeZone's time zone ID.
    142      * @param savingsStartMonth The daylight savings starting month. Month is
    143      *                          0-based. eg, 0 for January.
    144      * @param savingsStartDayOfWeekInMonth   The daylight savings starting
    145      *                          day-of-week-in-month. See setStartRule() for a
    146      *                          complete explanation.
    147      * @param savingsStartDayOfWeek The daylight savings starting day-of-week.
    148      *                          See setStartRule() for a complete explanation.
    149      * @param savingsStartTime  The daylight savings starting time, expressed as the
    150      *                          number of milliseconds after midnight.
    151      * @param savingsEndMonth   The daylight savings ending month. Month is
    152      *                          0-based. eg, 0 for January.
    153      * @param savingsEndDayOfWeekInMonth     The daylight savings ending day-of-week-in-month.
    154      *                          See setStartRule() for a complete explanation.
    155      * @param savingsEndDayOfWeek The daylight savings ending day-of-week.
    156      *                          See setStartRule() for a complete explanation.
    157      * @param savingsEndTime    The daylight savings ending time, expressed as the
    158      *                          number of milliseconds after midnight.
    159      * @param status            An UErrorCode to receive the status.
    160      * @stable ICU 2.0
    161      */
    162     SimpleTimeZone(int32_t rawOffsetGMT, const UnicodeString& ID,
    163         int8_t savingsStartMonth, int8_t savingsStartDayOfWeekInMonth,
    164         int8_t savingsStartDayOfWeek, int32_t savingsStartTime,
    165         int8_t savingsEndMonth, int8_t savingsEndDayOfWeekInMonth,
    166         int8_t savingsEndDayOfWeek, int32_t savingsEndTime,
    167         UErrorCode& status);
    168     /**
    169      * Construct a SimpleTimeZone with the given raw GMT offset, time zone ID,
    170      * and times to start and end daylight savings time. To create a TimeZone that
    171      * doesn't observe daylight savings time, don't use this constructor; use
    172      * SimpleTimeZone(rawOffset, ID) instead. Normally, you should use
    173      * TimeZone.createInstance() to create a TimeZone instead of creating a
    174      * SimpleTimeZone directly with this constructor.
    175      * <P>
    176      * Various types of daylight-savings time rules can be specfied by using different
    177      * values for startDay and startDayOfWeek and endDay and endDayOfWeek.  For a
    178      * complete explanation of how these parameters work, see the documentation for
    179      * setStartRule().
    180      *
    181      * @param rawOffsetGMT      The new SimpleTimeZone's raw GMT offset
    182      * @param ID                The new SimpleTimeZone's time zone ID.
    183      * @param savingsStartMonth The daylight savings starting month. Month is
    184      *                          0-based. eg, 0 for January.
    185      * @param savingsStartDayOfWeekInMonth   The daylight savings starting
    186      *                          day-of-week-in-month. See setStartRule() for a
    187      *                          complete explanation.
    188      * @param savingsStartDayOfWeek The daylight savings starting day-of-week.
    189      *                          See setStartRule() for a complete explanation.
    190      * @param savingsStartTime  The daylight savings starting time, expressed as the
    191      *                          number of milliseconds after midnight.
    192      * @param savingsEndMonth   The daylight savings ending month. Month is
    193      *                          0-based. eg, 0 for January.
    194      * @param savingsEndDayOfWeekInMonth     The daylight savings ending day-of-week-in-month.
    195      *                          See setStartRule() for a complete explanation.
    196      * @param savingsEndDayOfWeek The daylight savings ending day-of-week.
    197      *                          See setStartRule() for a complete explanation.
    198      * @param savingsEndTime    The daylight savings ending time, expressed as the
    199      *                          number of milliseconds after midnight.
    200      * @param savingsDST        The number of milliseconds added to standard time
    201      *                          to get DST time. Default is one hour.
    202      * @param status            An UErrorCode to receive the status.
    203      * @stable ICU 2.0
    204      */
    205     SimpleTimeZone(int32_t rawOffsetGMT, const UnicodeString& ID,
    206         int8_t savingsStartMonth, int8_t savingsStartDayOfWeekInMonth,
    207         int8_t savingsStartDayOfWeek, int32_t savingsStartTime,
    208         int8_t savingsEndMonth, int8_t savingsEndDayOfWeekInMonth,
    209         int8_t savingsEndDayOfWeek, int32_t savingsEndTime,
    210         int32_t savingsDST, UErrorCode& status);
    211 
    212     /**
    213      * Construct a SimpleTimeZone with the given raw GMT offset, time zone ID,
    214      * and times to start and end daylight savings time. To create a TimeZone that
    215      * doesn't observe daylight savings time, don't use this constructor; use
    216      * SimpleTimeZone(rawOffset, ID) instead. Normally, you should use
    217      * TimeZone.createInstance() to create a TimeZone instead of creating a
    218      * SimpleTimeZone directly with this constructor.
    219      * <P>
    220      * Various types of daylight-savings time rules can be specfied by using different
    221      * values for startDay and startDayOfWeek and endDay and endDayOfWeek.  For a
    222      * complete explanation of how these parameters work, see the documentation for
    223      * setStartRule().
    224      *
    225      * @param rawOffsetGMT      The new SimpleTimeZone's raw GMT offset
    226      * @param ID                The new SimpleTimeZone's time zone ID.
    227      * @param savingsStartMonth The daylight savings starting month. Month is
    228      *                          0-based. eg, 0 for January.
    229      * @param savingsStartDayOfWeekInMonth   The daylight savings starting
    230      *                          day-of-week-in-month. See setStartRule() for a
    231      *                          complete explanation.
    232      * @param savingsStartDayOfWeek The daylight savings starting day-of-week.
    233      *                          See setStartRule() for a complete explanation.
    234      * @param savingsStartTime  The daylight savings starting time, expressed as the
    235      *                          number of milliseconds after midnight.
    236      * @param savingsStartTimeMode Whether the start time is local wall time, local
    237      *                          standard time, or UTC time. Default is local wall time.
    238      * @param savingsEndMonth   The daylight savings ending month. Month is
    239      *                          0-based. eg, 0 for January.
    240      * @param savingsEndDayOfWeekInMonth     The daylight savings ending day-of-week-in-month.
    241      *                          See setStartRule() for a complete explanation.
    242      * @param savingsEndDayOfWeek The daylight savings ending day-of-week.
    243      *                          See setStartRule() for a complete explanation.
    244      * @param savingsEndTime    The daylight savings ending time, expressed as the
    245      *                          number of milliseconds after midnight.
    246      * @param savingsEndTimeMode Whether the end time is local wall time, local
    247      *                          standard time, or UTC time. Default is local wall time.
    248      * @param savingsDST        The number of milliseconds added to standard time
    249      *                          to get DST time. Default is one hour.
    250      * @param status            An UErrorCode to receive the status.
    251      * @stable ICU 2.0
    252      */
    253     SimpleTimeZone(int32_t rawOffsetGMT, const UnicodeString& ID,
    254         int8_t savingsStartMonth, int8_t savingsStartDayOfWeekInMonth,
    255         int8_t savingsStartDayOfWeek, int32_t savingsStartTime,
    256         TimeMode savingsStartTimeMode,
    257         int8_t savingsEndMonth, int8_t savingsEndDayOfWeekInMonth,
    258         int8_t savingsEndDayOfWeek, int32_t savingsEndTime, TimeMode savingsEndTimeMode,
    259         int32_t savingsDST, UErrorCode& status);
    260 
    261     /**
    262      * Sets the daylight savings starting year, that is, the year this time zone began
    263      * observing its specified daylight savings time rules.  The time zone is considered
    264      * not to observe daylight savings time prior to that year; SimpleTimeZone doesn't
    265      * support historical daylight-savings-time rules.
    266      * @param year the daylight savings starting year.
    267      * @stable ICU 2.0
    268      */
    269     void setStartYear(int32_t year);
    270 
    271     /**
    272      * Sets the daylight savings starting rule. For example, in the U.S., Daylight Savings
    273      * Time starts at the second Sunday in March, at 2 AM in standard time.
    274      * Therefore, you can set the start rule by calling:
    275      * setStartRule(UCAL_MARCH, 2, UCAL_SUNDAY, 2*60*60*1000);
    276      * The dayOfWeekInMonth and dayOfWeek parameters together specify how to calculate
    277      * the exact starting date.  Their exact meaning depend on their respective signs,
    278      * allowing various types of rules to be constructed, as follows:
    279      * <ul>
    280      *   <li>If both dayOfWeekInMonth and dayOfWeek are positive, they specify the
    281      *       day of week in the month (e.g., (2, WEDNESDAY) is the second Wednesday
    282      *       of the month).</li>
    283      *   <li>If dayOfWeek is positive and dayOfWeekInMonth is negative, they specify
    284      *       the day of week in the month counting backward from the end of the month.
    285      *       (e.g., (-1, MONDAY) is the last Monday in the month)</li>
    286      *   <li>If dayOfWeek is zero and dayOfWeekInMonth is positive, dayOfWeekInMonth
    287      *       specifies the day of the month, regardless of what day of the week it is.
    288      *       (e.g., (10, 0) is the tenth day of the month)</li>
    289      *   <li>If dayOfWeek is zero and dayOfWeekInMonth is negative, dayOfWeekInMonth
    290      *       specifies the day of the month counting backward from the end of the
    291      *       month, regardless of what day of the week it is (e.g., (-2, 0) is the
    292      *       next-to-last day of the month).</li>
    293      *   <li>If dayOfWeek is negative and dayOfWeekInMonth is positive, they specify the
    294      *       first specified day of the week on or after the specfied day of the month.
    295      *       (e.g., (15, -SUNDAY) is the first Sunday after the 15th of the month
    296      *       [or the 15th itself if the 15th is a Sunday].)</li>
    297      *   <li>If dayOfWeek and DayOfWeekInMonth are both negative, they specify the
    298      *       last specified day of the week on or before the specified day of the month.
    299      *       (e.g., (-20, -TUESDAY) is the last Tuesday before the 20th of the month
    300      *       [or the 20th itself if the 20th is a Tuesday].)</li>
    301      * </ul>
    302      * @param month the daylight savings starting month. Month is 0-based.
    303      * eg, 0 for January.
    304      * @param dayOfWeekInMonth the daylight savings starting
    305      * day-of-week-in-month. Please see the member description for an example.
    306      * @param dayOfWeek the daylight savings starting day-of-week. Please see
    307      * the member description for an example.
    308      * @param time the daylight savings starting time. Please see the member
    309      * description for an example.
    310      * @param status An UErrorCode
    311      * @stable ICU 2.0
    312      */
    313     void setStartRule(int32_t month, int32_t dayOfWeekInMonth, int32_t dayOfWeek,
    314                       int32_t time, UErrorCode& status);
    315     /**
    316      * Sets the daylight savings starting rule. For example, in the U.S., Daylight Savings
    317      * Time starts at the second Sunday in March, at 2 AM in standard time.
    318      * Therefore, you can set the start rule by calling:
    319      * setStartRule(UCAL_MARCH, 2, UCAL_SUNDAY, 2*60*60*1000);
    320      * The dayOfWeekInMonth and dayOfWeek parameters together specify how to calculate
    321      * the exact starting date.  Their exact meaning depend on their respective signs,
    322      * allowing various types of rules to be constructed, as follows:
    323      * <ul>
    324      *   <li>If both dayOfWeekInMonth and dayOfWeek are positive, they specify the
    325      *       day of week in the month (e.g., (2, WEDNESDAY) is the second Wednesday
    326      *       of the month).</li>
    327      *   <li>If dayOfWeek is positive and dayOfWeekInMonth is negative, they specify
    328      *       the day of week in the month counting backward from the end of the month.
    329      *       (e.g., (-1, MONDAY) is the last Monday in the month)</li>
    330      *   <li>If dayOfWeek is zero and dayOfWeekInMonth is positive, dayOfWeekInMonth
    331      *       specifies the day of the month, regardless of what day of the week it is.
    332      *       (e.g., (10, 0) is the tenth day of the month)</li>
    333      *   <li>If dayOfWeek is zero and dayOfWeekInMonth is negative, dayOfWeekInMonth
    334      *       specifies the day of the month counting backward from the end of the
    335      *       month, regardless of what day of the week it is (e.g., (-2, 0) is the
    336      *       next-to-last day of the month).</li>
    337      *   <li>If dayOfWeek is negative and dayOfWeekInMonth is positive, they specify the
    338      *       first specified day of the week on or after the specfied day of the month.
    339      *       (e.g., (15, -SUNDAY) is the first Sunday after the 15th of the month
    340      *       [or the 15th itself if the 15th is a Sunday].)</li>
    341      *   <li>If dayOfWeek and DayOfWeekInMonth are both negative, they specify the
    342      *       last specified day of the week on or before the specified day of the month.
    343      *       (e.g., (-20, -TUESDAY) is the last Tuesday before the 20th of the month
    344      *       [or the 20th itself if the 20th is a Tuesday].)</li>
    345      * </ul>
    346      * @param month the daylight savings starting month. Month is 0-based.
    347      * eg, 0 for January.
    348      * @param dayOfWeekInMonth the daylight savings starting
    349      * day-of-week-in-month. Please see the member description for an example.
    350      * @param dayOfWeek the daylight savings starting day-of-week. Please see
    351      * the member description for an example.
    352      * @param time the daylight savings starting time. Please see the member
    353      * description for an example.
    354      * @param mode whether the time is local wall time, local standard time,
    355      * or UTC time. Default is local wall time.
    356      * @param status An UErrorCode
    357      * @stable ICU 2.0
    358      */
    359     void setStartRule(int32_t month, int32_t dayOfWeekInMonth, int32_t dayOfWeek,
    360                       int32_t time, TimeMode mode, UErrorCode& status);
    361 
    362     /**
    363      * Sets the DST start rule to a fixed date within a month.
    364      *
    365      * @param month         The month in which this rule occurs (0-based).
    366      * @param dayOfMonth    The date in that month (1-based).
    367      * @param time          The time of that day (number of millis after midnight)
    368      *                      when DST takes effect in local wall time, which is
    369      *                      standard time in this case.
    370      * @param status An UErrorCode
    371      * @stable ICU 2.0
    372      */
    373     void setStartRule(int32_t month, int32_t dayOfMonth, int32_t time,
    374                       UErrorCode& status);
    375     /**
    376      * Sets the DST start rule to a fixed date within a month.
    377      *
    378      * @param month         The month in which this rule occurs (0-based).
    379      * @param dayOfMonth    The date in that month (1-based).
    380      * @param time          The time of that day (number of millis after midnight)
    381      *                      when DST takes effect in local wall time, which is
    382      *                      standard time in this case.
    383      * @param mode whether the time is local wall time, local standard time,
    384      * or UTC time. Default is local wall time.
    385      * @param status An UErrorCode
    386      * @stable ICU 2.0
    387      */
    388     void setStartRule(int32_t month, int32_t dayOfMonth, int32_t time,
    389                       TimeMode mode, UErrorCode& status);
    390 
    391     /**
    392      * Sets the DST start rule to a weekday before or after a give date within
    393      * a month, e.g., the first Monday on or after the 8th.
    394      *
    395      * @param month         The month in which this rule occurs (0-based).
    396      * @param dayOfMonth    A date within that month (1-based).
    397      * @param dayOfWeek     The day of the week on which this rule occurs.
    398      * @param time          The time of that day (number of millis after midnight)
    399      *                      when DST takes effect in local wall time, which is
    400      *                      standard time in this case.
    401      * @param after         If true, this rule selects the first dayOfWeek on
    402      *                      or after dayOfMonth.  If false, this rule selects
    403      *                      the last dayOfWeek on or before dayOfMonth.
    404      * @param status An UErrorCode
    405      * @stable ICU 2.0
    406      */
    407     void setStartRule(int32_t month, int32_t dayOfMonth, int32_t dayOfWeek,
    408                       int32_t time, UBool after, UErrorCode& status);
    409     /**
    410      * Sets the DST start rule to a weekday before or after a give date within
    411      * a month, e.g., the first Monday on or after the 8th.
    412      *
    413      * @param month         The month in which this rule occurs (0-based).
    414      * @param dayOfMonth    A date within that month (1-based).
    415      * @param dayOfWeek     The day of the week on which this rule occurs.
    416      * @param time          The time of that day (number of millis after midnight)
    417      *                      when DST takes effect in local wall time, which is
    418      *                      standard time in this case.
    419      * @param mode whether the time is local wall time, local standard time,
    420      * or UTC time. Default is local wall time.
    421      * @param after         If true, this rule selects the first dayOfWeek on
    422      *                      or after dayOfMonth.  If false, this rule selects
    423      *                      the last dayOfWeek on or before dayOfMonth.
    424      * @param status An UErrorCode
    425      * @stable ICU 2.0
    426      */
    427     void setStartRule(int32_t month, int32_t dayOfMonth, int32_t dayOfWeek,
    428                       int32_t time, TimeMode mode, UBool after, UErrorCode& status);
    429 
    430     /**
    431      * Sets the daylight savings ending rule. For example, if Daylight
    432      * Savings Time ends at the last (-1) Sunday in October, at 2 AM in standard time.
    433      * Therefore, you can set the end rule by calling:
    434      * <pre>
    435      *    setEndRule(UCAL_OCTOBER, -1, UCAL_SUNDAY, 2*60*60*1000);
    436      * </pre>
    437      * Various other types of rules can be specified by manipulating the dayOfWeek
    438      * and dayOfWeekInMonth parameters.  For complete details, see the documentation
    439      * for setStartRule().
    440      *
    441      * @param month the daylight savings ending month. Month is 0-based.
    442      * eg, 0 for January.
    443      * @param dayOfWeekInMonth the daylight savings ending
    444      * day-of-week-in-month. See setStartRule() for a complete explanation.
    445      * @param dayOfWeek the daylight savings ending day-of-week. See setStartRule()
    446      * for a complete explanation.
    447      * @param time the daylight savings ending time. Please see the member
    448      * description for an example.
    449      * @param status An UErrorCode
    450      * @stable ICU 2.0
    451      */
    452     void setEndRule(int32_t month, int32_t dayOfWeekInMonth, int32_t dayOfWeek,
    453                     int32_t time, UErrorCode& status);
    454 
    455     /**
    456      * Sets the daylight savings ending rule. For example, if Daylight
    457      * Savings Time ends at the last (-1) Sunday in October, at 2 AM in standard time.
    458      * Therefore, you can set the end rule by calling:
    459      * <pre>
    460      *    setEndRule(UCAL_OCTOBER, -1, UCAL_SUNDAY, 2*60*60*1000);
    461      * </pre>
    462      * Various other types of rules can be specified by manipulating the dayOfWeek
    463      * and dayOfWeekInMonth parameters.  For complete details, see the documentation
    464      * for setStartRule().
    465      *
    466      * @param month the daylight savings ending month. Month is 0-based.
    467      * eg, 0 for January.
    468      * @param dayOfWeekInMonth the daylight savings ending
    469      * day-of-week-in-month. See setStartRule() for a complete explanation.
    470      * @param dayOfWeek the daylight savings ending day-of-week. See setStartRule()
    471      * for a complete explanation.
    472      * @param time the daylight savings ending time. Please see the member
    473      * description for an example.
    474      * @param mode whether the time is local wall time, local standard time,
    475      * or UTC time. Default is local wall time.
    476      * @param status An UErrorCode
    477      * @stable ICU 2.0
    478      */
    479     void setEndRule(int32_t month, int32_t dayOfWeekInMonth, int32_t dayOfWeek,
    480                     int32_t time, TimeMode mode, UErrorCode& status);
    481 
    482     /**
    483      * Sets the DST end rule to a fixed date within a month.
    484      *
    485      * @param month         The month in which this rule occurs (0-based).
    486      * @param dayOfMonth    The date in that month (1-based).
    487      * @param time          The time of that day (number of millis after midnight)
    488      *                      when DST ends in local wall time, which is daylight
    489      *                      time in this case.
    490      * @param status An UErrorCode
    491      * @stable ICU 2.0
    492      */
    493     void setEndRule(int32_t month, int32_t dayOfMonth, int32_t time, UErrorCode& status);
    494 
    495     /**
    496      * Sets the DST end rule to a fixed date within a month.
    497      *
    498      * @param month         The month in which this rule occurs (0-based).
    499      * @param dayOfMonth    The date in that month (1-based).
    500      * @param time          The time of that day (number of millis after midnight)
    501      *                      when DST ends in local wall time, which is daylight
    502      *                      time in this case.
    503      * @param mode whether the time is local wall time, local standard time,
    504      * or UTC time. Default is local wall time.
    505      * @param status An UErrorCode
    506      * @stable ICU 2.0
    507      */
    508     void setEndRule(int32_t month, int32_t dayOfMonth, int32_t time,
    509                     TimeMode mode, UErrorCode& status);
    510 
    511     /**
    512      * Sets the DST end rule to a weekday before or after a give date within
    513      * a month, e.g., the first Monday on or after the 8th.
    514      *
    515      * @param month         The month in which this rule occurs (0-based).
    516      * @param dayOfMonth    A date within that month (1-based).
    517      * @param dayOfWeek     The day of the week on which this rule occurs.
    518      * @param time          The time of that day (number of millis after midnight)
    519      *                      when DST ends in local wall time, which is daylight
    520      *                      time in this case.
    521      * @param after         If true, this rule selects the first dayOfWeek on
    522      *                      or after dayOfMonth.  If false, this rule selects
    523      *                      the last dayOfWeek on or before dayOfMonth.
    524      * @param status An UErrorCode
    525      * @stable ICU 2.0
    526      */
    527     void setEndRule(int32_t month, int32_t dayOfMonth, int32_t dayOfWeek,
    528                     int32_t time, UBool after, UErrorCode& status);
    529 
    530     /**
    531      * Sets the DST end rule to a weekday before or after a give date within
    532      * a month, e.g., the first Monday on or after the 8th.
    533      *
    534      * @param month         The month in which this rule occurs (0-based).
    535      * @param dayOfMonth    A date within that month (1-based).
    536      * @param dayOfWeek     The day of the week on which this rule occurs.
    537      * @param time          The time of that day (number of millis after midnight)
    538      *                      when DST ends in local wall time, which is daylight
    539      *                      time in this case.
    540      * @param mode whether the time is local wall time, local standard time,
    541      * or UTC time. Default is local wall time.
    542      * @param after         If true, this rule selects the first dayOfWeek on
    543      *                      or after dayOfMonth.  If false, this rule selects
    544      *                      the last dayOfWeek on or before dayOfMonth.
    545      * @param status An UErrorCode
    546      * @stable ICU 2.0
    547      */
    548     void setEndRule(int32_t month, int32_t dayOfMonth, int32_t dayOfWeek,
    549                     int32_t time, TimeMode mode, UBool after, UErrorCode& status);
    550 
    551     /**
    552      * Returns the TimeZone's adjusted GMT offset (i.e., the number of milliseconds to add
    553      * to GMT to get local time in this time zone, taking daylight savings time into
    554      * account) as of a particular reference date.  The reference date is used to determine
    555      * whether daylight savings time is in effect and needs to be figured into the offset
    556      * that is returned (in other words, what is the adjusted GMT offset in this time zone
    557      * at this particular date and time?).  For the time zones produced by createTimeZone(),
    558      * the reference data is specified according to the Gregorian calendar, and the date
    559      * and time fields are in GMT, NOT local time.
    560      *
    561      * @param era        The reference date's era
    562      * @param year       The reference date's year
    563      * @param month      The reference date's month (0-based; 0 is January)
    564      * @param day        The reference date's day-in-month (1-based)
    565      * @param dayOfWeek  The reference date's day-of-week (1-based; 1 is Sunday)
    566      * @param millis     The reference date's milliseconds in day, UTT (NOT local time).
    567      * @param status     An UErrorCode to receive the status.
    568      * @return           The offset in milliseconds to add to GMT to get local time.
    569      * @stable ICU 2.0
    570      */
    571     virtual int32_t getOffset(uint8_t era, int32_t year, int32_t month, int32_t day,
    572                               uint8_t dayOfWeek, int32_t millis, UErrorCode& status) const;
    573 
    574     /**
    575      * Gets the time zone offset, for current date, modified in case of
    576      * daylight savings. This is the offset to add *to* UTC to get local time.
    577      * @param era the era of the given date.
    578      * @param year the year in the given date.
    579      * @param month the month in the given date.
    580      * Month is 0-based. e.g., 0 for January.
    581      * @param day the day-in-month of the given date.
    582      * @param dayOfWeek the day-of-week of the given date.
    583      * @param milliseconds the millis in day in <em>standard</em> local time.
    584      * @param monthLength the length of the given month in days.
    585      * @param status     An UErrorCode to receive the status.
    586      * @return the offset to add *to* GMT to get local time.
    587      * @stable ICU 2.0
    588      */
    589     virtual int32_t getOffset(uint8_t era, int32_t year, int32_t month, int32_t day,
    590                            uint8_t dayOfWeek, int32_t milliseconds,
    591                            int32_t monthLength, UErrorCode& status) const;
    592     /**
    593      * Gets the time zone offset, for current date, modified in case of
    594      * daylight savings. This is the offset to add *to* UTC to get local time.
    595      * @param era the era of the given date.
    596      * @param year the year in the given date.
    597      * @param month the month in the given date.
    598      * Month is 0-based. e.g., 0 for January.
    599      * @param day the day-in-month of the given date.
    600      * @param dayOfWeek the day-of-week of the given date.
    601      * @param milliseconds the millis in day in <em>standard</em> local time.
    602      * @param monthLength the length of the given month in days.
    603      * @param prevMonthLength length of the previous month in days.
    604      * @param status     An UErrorCode to receive the status.
    605      * @return the offset to add *to* GMT to get local time.
    606      * @stable ICU 2.0
    607      */
    608     virtual int32_t getOffset(uint8_t era, int32_t year, int32_t month, int32_t day,
    609                               uint8_t dayOfWeek, int32_t milliseconds,
    610                               int32_t monthLength, int32_t prevMonthLength,
    611                               UErrorCode& status) const;
    612 
    613     /**
    614      * Redeclared TimeZone method.  This implementation simply calls
    615      * the base class method, which otherwise would be hidden.
    616      * @stable ICU 2.8
    617      */
    618     virtual void getOffset(UDate date, UBool local, int32_t& rawOffset,
    619                            int32_t& dstOffset, UErrorCode& ec) const;
    620 
    621     /**
    622      * Get time zone offsets from local wall time.
    623      * @internal
    624      */
    625     virtual void getOffsetFromLocal(UDate date, int32_t nonExistingTimeOpt, int32_t duplicatedTimeOpt,
    626         int32_t& rawOffset, int32_t& dstOffset, UErrorCode& status) const;
    627 
    628     /**
    629      * Returns the TimeZone's raw GMT offset (i.e., the number of milliseconds to add
    630      * to GMT to get local time, before taking daylight savings time into account).
    631      *
    632      * @return   The TimeZone's raw GMT offset.
    633      * @stable ICU 2.0
    634      */
    635     virtual int32_t getRawOffset(void) const;
    636 
    637     /**
    638      * Sets the TimeZone's raw GMT offset (i.e., the number of milliseconds to add
    639      * to GMT to get local time, before taking daylight savings time into account).
    640      *
    641      * @param offsetMillis  The new raw GMT offset for this time zone.
    642      * @stable ICU 2.0
    643      */
    644     virtual void setRawOffset(int32_t offsetMillis);
    645 
    646     /**
    647      * Sets the amount of time in ms that the clock is advanced during DST.
    648      * @param millisSavedDuringDST the number of milliseconds the time is
    649      * advanced with respect to standard time when the daylight savings rules
    650      * are in effect. A positive number, typically one hour (3600000).
    651      * @param status  An UErrorCode to receive the status.
    652      * @stable ICU 2.0
    653      */
    654     void setDSTSavings(int32_t millisSavedDuringDST, UErrorCode& status);
    655 
    656     /**
    657      * Returns the amount of time in ms that the clock is advanced during DST.
    658      * @return the number of milliseconds the time is
    659      * advanced with respect to standard time when the daylight savings rules
    660      * are in effect. A positive number, typically one hour (3600000).
    661      * @stable ICU 2.0
    662      */
    663     virtual int32_t getDSTSavings(void) const;
    664 
    665     /**
    666      * Queries if this TimeZone uses Daylight Savings Time.
    667      *
    668      * @return   True if this TimeZone uses Daylight Savings Time; false otherwise.
    669      * @stable ICU 2.0
    670      */
    671     virtual UBool useDaylightTime(void) const;
    672 
    673     /**
    674      * Returns true if the given date is within the period when daylight savings time
    675      * is in effect; false otherwise.  If the TimeZone doesn't observe daylight savings
    676      * time, this functions always returns false.
    677      * This method is wasteful since it creates a new GregorianCalendar and
    678      * deletes it each time it is called. This is a deprecated method
    679      * and provided only for Java compatibility.
    680      *
    681      * @param date The date to test.
    682      * @param status  An UErrorCode to receive the status.
    683      * @return true if the given date is in Daylight Savings Time;
    684      * false otherwise.
    685      * @deprecated ICU 2.4. Use Calendar::inDaylightTime() instead.
    686      */
    687     virtual UBool inDaylightTime(UDate date, UErrorCode& status) const;
    688 
    689     /**
    690      * Return true if this zone has the same rules and offset as another zone.
    691      * @param other the TimeZone object to be compared with
    692      * @return true if the given zone has the same rules and offset as this one
    693      * @stable ICU 2.0
    694      */
    695     UBool hasSameRules(const TimeZone& other) const;
    696 
    697     /**
    698      * Clones TimeZone objects polymorphically. Clients are responsible for deleting
    699      * the TimeZone object cloned.
    700      *
    701      * @return   A new copy of this TimeZone object.
    702      * @stable ICU 2.0
    703      */
    704     virtual TimeZone* clone(void) const;
    705 
    706     /**
    707      * Gets the first time zone transition after the base time.
    708      * @param base      The base time.
    709      * @param inclusive Whether the base time is inclusive or not.
    710      * @param result    Receives the first transition after the base time.
    711      * @return  TRUE if the transition is found.
    712      * @stable ICU 3.8
    713      */
    714     virtual UBool getNextTransition(UDate base, UBool inclusive, TimeZoneTransition& result) const;
    715 
    716     /**
    717      * Gets the most recent time zone transition before the base time.
    718      * @param base      The base time.
    719      * @param inclusive Whether the base time is inclusive or not.
    720      * @param result    Receives the most recent transition before the base time.
    721      * @return  TRUE if the transition is found.
    722      * @stable ICU 3.8
    723      */
    724     virtual UBool getPreviousTransition(UDate base, UBool inclusive, TimeZoneTransition& result) const;
    725 
    726     /**
    727      * Returns the number of <code>TimeZoneRule</code>s which represents time transitions,
    728      * for this time zone, that is, all <code>TimeZoneRule</code>s for this time zone except
    729      * <code>InitialTimeZoneRule</code>.  The return value range is 0 or any positive value.
    730      * @param status    Receives error status code.
    731      * @return The number of <code>TimeZoneRule</code>s representing time transitions.
    732      * @stable ICU 3.8
    733      */
    734     virtual int32_t countTransitionRules(UErrorCode& status) const;
    735 
    736     /**
    737      * Gets the <code>InitialTimeZoneRule</code> and the set of <code>TimeZoneRule</code>
    738      * which represent time transitions for this time zone.  On successful return,
    739      * the argument initial points to non-NULL <code>InitialTimeZoneRule</code> and
    740      * the array trsrules is filled with 0 or multiple <code>TimeZoneRule</code>
    741      * instances up to the size specified by trscount.  The results are referencing the
    742      * rule instance held by this time zone instance.  Therefore, after this time zone
    743      * is destructed, they are no longer available.
    744      * @param initial       Receives the initial timezone rule
    745      * @param trsrules      Receives the timezone transition rules
    746      * @param trscount      On input, specify the size of the array 'transitions' receiving
    747      *                      the timezone transition rules.  On output, actual number of
    748      *                      rules filled in the array will be set.
    749      * @param status        Receives error status code.
    750      * @stable ICU 3.8
    751      */
    752     virtual void getTimeZoneRules(const InitialTimeZoneRule*& initial,
    753         const TimeZoneRule* trsrules[], int32_t& trscount, UErrorCode& status) const;
    754 
    755 
    756 public:
    757 
    758     /**
    759      * Override TimeZone Returns a unique class ID POLYMORPHICALLY. Pure virtual
    760      * override. This method is to implement a simple version of RTTI, since not all C++
    761      * compilers support genuine RTTI. Polymorphic operator==() and clone() methods call
    762      * this method.
    763      *
    764      * @return   The class ID for this object. All objects of a given class have the
    765      *           same class ID. Objects of other classes have different class IDs.
    766      * @stable ICU 2.0
    767      */
    768     virtual UClassID getDynamicClassID(void) const;
    769 
    770     /**
    771      * Return the class ID for this class. This is useful only for comparing to a return
    772      * value from getDynamicClassID(). For example:
    773      * <pre>
    774      * .   Base* polymorphic_pointer = createPolymorphicObject();
    775      * .   if (polymorphic_pointer->getDynamicClassID() ==
    776      * .       Derived::getStaticClassID()) ...
    777      * </pre>
    778      * @return   The class ID for all objects of this class.
    779      * @stable ICU 2.0
    780      */
    781     static UClassID U_EXPORT2 getStaticClassID(void);
    782 
    783 private:
    784     /**
    785      * Constants specifying values of startMode and endMode.
    786      */
    787     enum EMode
    788     {
    789         DOM_MODE = 1,
    790         DOW_IN_MONTH_MODE,
    791         DOW_GE_DOM_MODE,
    792         DOW_LE_DOM_MODE
    793     };
    794 
    795     SimpleTimeZone(); // default constructor not implemented
    796 
    797     /**
    798      * Internal construction method.
    799      * @param rawOffsetGMT    The new SimpleTimeZone's raw GMT offset
    800      * @param startMonth      the month DST starts
    801      * @param startDay        the day DST starts
    802      * @param startDayOfWeek  the DOW DST starts
    803      * @param startTime       the time DST starts
    804      * @param startTimeMode   Whether the start time is local wall time, local
    805      *                        standard time, or UTC time. Default is local wall time.
    806      * @param endMonth        the month DST ends
    807      * @param endDay          the day DST ends
    808      * @param endDayOfWeek    the DOW DST ends
    809      * @param endTime         the time DST ends
    810      * @param endTimeMode     Whether the end time is local wall time, local
    811      *                        standard time, or UTC time. Default is local wall time.
    812      * @param dstSavings      The number of milliseconds added to standard time
    813      *                        to get DST time. Default is one hour.
    814      * @param status          An UErrorCode to receive the status.
    815      */
    816     void construct(int32_t rawOffsetGMT,
    817                    int8_t startMonth, int8_t startDay, int8_t startDayOfWeek,
    818                    int32_t startTime, TimeMode startTimeMode,
    819                    int8_t endMonth, int8_t endDay, int8_t endDayOfWeek,
    820                    int32_t endTime, TimeMode endTimeMode,
    821                    int32_t dstSavings, UErrorCode& status);
    822 
    823     /**
    824      * Compare a given date in the year to a rule. Return 1, 0, or -1, depending
    825      * on whether the date is after, equal to, or before the rule date. The
    826      * millis are compared directly against the ruleMillis, so any
    827      * standard-daylight adjustments must be handled by the caller.
    828      *
    829      * @return  1 if the date is after the rule date, -1 if the date is before
    830      *          the rule date, or 0 if the date is equal to the rule date.
    831      */
    832     static int32_t compareToRule(int8_t month, int8_t monthLen, int8_t prevMonthLen,
    833                                  int8_t dayOfMonth,
    834                                  int8_t dayOfWeek, int32_t millis, int32_t millisDelta,
    835                                  EMode ruleMode, int8_t ruleMonth, int8_t ruleDayOfWeek,
    836                                  int8_t ruleDay, int32_t ruleMillis);
    837 
    838     /**
    839      * Given a set of encoded rules in startDay and startDayOfMonth, decode
    840      * them and set the startMode appropriately.  Do the same for endDay and
    841      * endDayOfMonth.
    842      * <P>
    843      * Upon entry, the day of week variables may be zero or
    844      * negative, in order to indicate special modes.  The day of month
    845      * variables may also be negative.
    846      * <P>
    847      * Upon exit, the mode variables will be
    848      * set, and the day of week and day of month variables will be positive.
    849      * <P>
    850      * This method also recognizes a startDay or endDay of zero as indicating
    851      * no DST.
    852      */
    853     void decodeRules(UErrorCode& status);
    854     void decodeStartRule(UErrorCode& status);
    855     void decodeEndRule(UErrorCode& status);
    856 
    857     int8_t startMonth, startDay, startDayOfWeek;   // the month, day, DOW, and time DST starts
    858     int32_t startTime;
    859     TimeMode startTimeMode, endTimeMode; // Mode for startTime, endTime; see TimeMode
    860     int8_t endMonth, endDay, endDayOfWeek; // the month, day, DOW, and time DST ends
    861     int32_t endTime;
    862     int32_t startYear;  // the year these DST rules took effect
    863     int32_t rawOffset;  // the TimeZone's raw GMT offset
    864     UBool useDaylight; // flag indicating whether this TimeZone uses DST
    865     static const int8_t STATICMONTHLENGTH[12]; // lengths of the months
    866     EMode startMode, endMode;   // flags indicating what kind of rules the DST rules are
    867 
    868     /**
    869      * A positive value indicating the amount of time saved during DST in ms.
    870      * Typically one hour; sometimes 30 minutes.
    871      */
    872     int32_t dstSavings;
    873 
    874     /* Private for BasicTimeZone implementation */
    875     void checkTransitionRules(UErrorCode& status) const;
    876     void initTransitionRules(UErrorCode& status);
    877     void clearTransitionRules(void);
    878     void deleteTransitionRules(void);
    879     UBool   transitionRulesInitialized;
    880     InitialTimeZoneRule*    initialRule;
    881     TimeZoneTransition*     firstTransition;
    882     AnnualTimeZoneRule*     stdRule;
    883     AnnualTimeZoneRule*     dstRule;
    884 };
    885 
    886 inline void SimpleTimeZone::setStartRule(int32_t month, int32_t dayOfWeekInMonth,
    887                                          int32_t dayOfWeek,
    888                                          int32_t time, UErrorCode& status) {
    889     setStartRule(month, dayOfWeekInMonth, dayOfWeek, time, WALL_TIME, status);
    890 }
    891 
    892 inline void SimpleTimeZone::setStartRule(int32_t month, int32_t dayOfMonth,
    893                                          int32_t time,
    894                                          UErrorCode& status) {
    895     setStartRule(month, dayOfMonth, time, WALL_TIME, status);
    896 }
    897 
    898 inline void SimpleTimeZone::setStartRule(int32_t month, int32_t dayOfMonth,
    899                                          int32_t dayOfWeek,
    900                                          int32_t time, UBool after, UErrorCode& status) {
    901     setStartRule(month, dayOfMonth, dayOfWeek, time, WALL_TIME, after, status);
    902 }
    903 
    904 inline void SimpleTimeZone::setEndRule(int32_t month, int32_t dayOfWeekInMonth,
    905                                        int32_t dayOfWeek,
    906                                        int32_t time, UErrorCode& status) {
    907     setEndRule(month, dayOfWeekInMonth, dayOfWeek, time, WALL_TIME, status);
    908 }
    909 
    910 inline void SimpleTimeZone::setEndRule(int32_t month, int32_t dayOfMonth,
    911                                        int32_t time, UErrorCode& status) {
    912     setEndRule(month, dayOfMonth, time, WALL_TIME, status);
    913 }
    914 
    915 inline void SimpleTimeZone::setEndRule(int32_t month, int32_t dayOfMonth, int32_t dayOfWeek,
    916                                        int32_t time, UBool after, UErrorCode& status) {
    917     setEndRule(month, dayOfMonth, dayOfWeek, time, WALL_TIME, after, status);
    918 }
    919 
    920 inline void
    921 SimpleTimeZone::getOffset(UDate date, UBool local, int32_t& rawOffsetRef,
    922                           int32_t& dstOffsetRef, UErrorCode& ec) const {
    923     TimeZone::getOffset(date, local, rawOffsetRef, dstOffsetRef, ec);
    924 }
    925 
    926 U_NAMESPACE_END
    927 
    928 #endif /* #if !UCONFIG_NO_FORMATTING */
    929 
    930 #endif // _SIMPLETZ
    931