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