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) 2007-2013, International Business Machines Corporation and
      6 * others. All Rights Reserved.
      7 *******************************************************************************
      8 */
      9 #ifndef VTZONE_H
     10 #define VTZONE_H
     11 
     12 #include "unicode/utypes.h"
     13 
     14 /**
     15  * \file
     16  * \brief C++ API: RFC2445 VTIMEZONE support
     17  */
     18 
     19 #if !UCONFIG_NO_FORMATTING
     20 
     21 #include "unicode/basictz.h"
     22 
     23 U_NAMESPACE_BEGIN
     24 
     25 class VTZWriter;
     26 class VTZReader;
     27 class UVector;
     28 
     29 /**
     30  * <code>VTimeZone</code> is a class implementing RFC2445 VTIMEZONE.  You can create a
     31  * <code>VTimeZone</code> instance from a time zone ID supported by <code>TimeZone</code>.
     32  * With the <code>VTimeZone</code> instance created from the ID, you can write out the rule
     33  * in RFC2445 VTIMEZONE format.  Also, you can create a <code>VTimeZone</code> instance
     34  * from RFC2445 VTIMEZONE data stream, which allows you to calculate time
     35  * zone offset by the rules defined by the data. Or, you can create a
     36  * <code>VTimeZone</code> from any other ICU <code>BasicTimeZone</code>.
     37  * <br><br>
     38  * Note: The consumer of this class reading or writing VTIMEZONE data is responsible to
     39  * decode or encode Non-ASCII text.  Methods reading/writing VTIMEZONE data in this class
     40  * do nothing with MIME encoding.
     41  * @stable ICU 3.8
     42  */
     43 class U_I18N_API VTimeZone : public BasicTimeZone {
     44 public:
     45     /**
     46      * Copy constructor.
     47      * @param source    The <code>VTimeZone</code> object to be copied.
     48      * @stable ICU 3.8
     49      */
     50     VTimeZone(const VTimeZone& source);
     51 
     52     /**
     53      * Destructor.
     54      * @stable ICU 3.8
     55      */
     56     virtual ~VTimeZone();
     57 
     58     /**
     59      * Assignment operator.
     60      * @param right The object to be copied.
     61      * @stable ICU 3.8
     62      */
     63     VTimeZone& operator=(const VTimeZone& right);
     64 
     65     /**
     66      * Return true if the given <code>TimeZone</code> objects are
     67      * semantically equal. Objects of different subclasses are considered unequal.
     68      * @param that  The object to be compared with.
     69      * @return  true if the given <code>TimeZone</code> objects are
     70       *semantically equal.
     71      * @stable ICU 3.8
     72      */
     73     virtual UBool operator==(const TimeZone& that) const;
     74 
     75     /**
     76      * Return true if the given <code>TimeZone</code> objects are
     77      * semantically unequal. Objects of different subclasses are considered unequal.
     78      * @param that  The object to be compared with.
     79      * @return  true if the given <code>TimeZone</code> objects are
     80      * semantically unequal.
     81      * @stable ICU 3.8
     82      */
     83     virtual UBool operator!=(const TimeZone& that) const;
     84 
     85     /**
     86      * Create a <code>VTimeZone</code> instance by the time zone ID.
     87      * @param ID The time zone ID, such as America/New_York
     88      * @return A <code>VTimeZone</code> object initialized by the time zone ID,
     89      * or NULL when the ID is unknown.
     90      * @stable ICU 3.8
     91      */
     92     static VTimeZone* createVTimeZoneByID(const UnicodeString& ID);
     93 
     94     /**
     95      * Create a <code>VTimeZone</code> instance using a basic time zone.
     96      * @param basicTZ The basic time zone instance
     97      * @param status Output param to filled in with a success or an error.
     98      * @return A <code>VTimeZone</code> object initialized by the basic time zone.
     99      * @stable ICU 4.6
    100      */
    101     static VTimeZone* createVTimeZoneFromBasicTimeZone(const BasicTimeZone& basicTZ,
    102                                                        UErrorCode &status);
    103 
    104     /**
    105      * Create a <code>VTimeZone</code> instance by RFC2445 VTIMEZONE data
    106      *
    107      * @param vtzdata The string including VTIMEZONE data block
    108      * @param status Output param to filled in with a success or an error.
    109      * @return A <code>VTimeZone</code> initialized by the VTIMEZONE data or
    110      * NULL if failed to load the rule from the VTIMEZONE data.
    111      * @stable ICU 3.8
    112      */
    113     static VTimeZone* createVTimeZone(const UnicodeString& vtzdata, UErrorCode& status);
    114 
    115     /**
    116      * Gets the RFC2445 TZURL property value.  When a <code>VTimeZone</code> instance was
    117      * created from VTIMEZONE data, the initial value is set by the TZURL property value
    118      * in the data.  Otherwise, the initial value is not set.
    119      * @param url Receives the RFC2445 TZURL property value.
    120      * @return TRUE if TZURL attribute is available and value is set.
    121      * @stable ICU 3.8
    122      */
    123     UBool getTZURL(UnicodeString& url) const;
    124 
    125     /**
    126      * Sets the RFC2445 TZURL property value.
    127      * @param url The TZURL property value.
    128      * @stable ICU 3.8
    129      */
    130     void setTZURL(const UnicodeString& url);
    131 
    132     /**
    133      * Gets the RFC2445 LAST-MODIFIED property value.  When a <code>VTimeZone</code> instance
    134      * was created from VTIMEZONE data, the initial value is set by the LAST-MODIFIED property
    135      * value in the data.  Otherwise, the initial value is not set.
    136      * @param lastModified Receives the last modified date.
    137      * @return TRUE if lastModified attribute is available and value is set.
    138      * @stable ICU 3.8
    139      */
    140     UBool getLastModified(UDate& lastModified) const;
    141 
    142     /**
    143      * Sets the RFC2445 LAST-MODIFIED property value.
    144      * @param lastModified The LAST-MODIFIED date.
    145      * @stable ICU 3.8
    146      */
    147     void setLastModified(UDate lastModified);
    148 
    149     /**
    150      * Writes RFC2445 VTIMEZONE data for this time zone
    151      * @param result Output param to filled in with the VTIMEZONE data.
    152      * @param status Output param to filled in with a success or an error.
    153      * @stable ICU 3.8
    154      */
    155     void write(UnicodeString& result, UErrorCode& status) const;
    156 
    157     /**
    158      * Writes RFC2445 VTIMEZONE data for this time zone applicalbe
    159      * for dates after the specified start time.
    160      * @param start The start date.
    161      * @param result Output param to filled in with the VTIMEZONE data.
    162      * @param status Output param to filled in with a success or an error.
    163      * @stable ICU 3.8
    164      */
    165     void write(UDate start, UnicodeString& result, UErrorCode& status) const;
    166 
    167     /**
    168      * Writes RFC2445 VTIMEZONE data applicalbe for the specified date.
    169      * Some common iCalendar implementations can only handle a single time
    170      * zone property or a pair of standard and daylight time properties using
    171      * BYDAY rule with day of week (such as BYDAY=1SUN).  This method produce
    172      * the VTIMEZONE data which can be handled these implementations.  The rules
    173      * produced by this method can be used only for calculating time zone offset
    174      * around the specified date.
    175      * @param time The date used for rule extraction.
    176      * @param result Output param to filled in with the VTIMEZONE data.
    177      * @param status Output param to filled in with a success or an error.
    178      * @stable ICU 3.8
    179      */
    180     void writeSimple(UDate time, UnicodeString& result, UErrorCode& status) const;
    181 
    182     /**
    183      * Clones TimeZone objects polymorphically. Clients are responsible for deleting
    184      * the TimeZone object cloned.
    185      * @return   A new copy of this TimeZone object.
    186      * @stable ICU 3.8
    187      */
    188     virtual TimeZone* clone(void) const;
    189 
    190     /**
    191      * Returns the TimeZone's adjusted GMT offset (i.e., the number of milliseconds to add
    192      * to GMT to get local time in this time zone, taking daylight savings time into
    193      * account) as of a particular reference date.  The reference date is used to determine
    194      * whether daylight savings time is in effect and needs to be figured into the offset
    195      * that is returned (in other words, what is the adjusted GMT offset in this time zone
    196      * at this particular date and time?).  For the time zones produced by createTimeZone(),
    197      * the reference data is specified according to the Gregorian calendar, and the date
    198      * and time fields are local standard time.
    199      *
    200      * <p>Note: Don't call this method. Instead, call the getOffset(UDate...) overload,
    201      * which returns both the raw and the DST offset for a given time. This method
    202      * is retained only for backward compatibility.
    203      *
    204      * @param era        The reference date's era
    205      * @param year       The reference date's year
    206      * @param month      The reference date's month (0-based; 0 is January)
    207      * @param day        The reference date's day-in-month (1-based)
    208      * @param dayOfWeek  The reference date's day-of-week (1-based; 1 is Sunday)
    209      * @param millis     The reference date's milliseconds in day, local standard time
    210      * @param status     Output param to filled in with a success or an error.
    211      * @return           The offset in milliseconds to add to GMT to get local time.
    212      * @stable ICU 3.8
    213      */
    214     virtual int32_t getOffset(uint8_t era, int32_t year, int32_t month, int32_t day,
    215                               uint8_t dayOfWeek, int32_t millis, UErrorCode& status) const;
    216 
    217     /**
    218      * Gets the time zone offset, for current date, modified in case of
    219      * daylight savings. This is the offset to add *to* UTC to get local time.
    220      *
    221      * <p>Note: Don't call this method. Instead, call the getOffset(UDate...) overload,
    222      * which returns both the raw and the DST offset for a given time. This method
    223      * is retained only for backward compatibility.
    224      *
    225      * @param era        The reference date's era
    226      * @param year       The reference date's year
    227      * @param month      The reference date's month (0-based; 0 is January)
    228      * @param day        The reference date's day-in-month (1-based)
    229      * @param dayOfWeek  The reference date's day-of-week (1-based; 1 is Sunday)
    230      * @param millis     The reference date's milliseconds in day, local standard time
    231      * @param monthLength The length of the given month in days.
    232      * @param status     Output param to filled in with a success or an error.
    233      * @return           The offset in milliseconds to add to GMT to get local time.
    234      * @stable ICU 3.8
    235      */
    236     virtual int32_t getOffset(uint8_t era, int32_t year, int32_t month, int32_t day,
    237                            uint8_t dayOfWeek, int32_t millis,
    238                            int32_t monthLength, UErrorCode& status) const;
    239 
    240     /**
    241      * Returns the time zone raw and GMT offset for the given moment
    242      * in time.  Upon return, local-millis = GMT-millis + rawOffset +
    243      * dstOffset.  All computations are performed in the proleptic
    244      * Gregorian calendar.  The default implementation in the TimeZone
    245      * class delegates to the 8-argument getOffset().
    246      *
    247      * @param date moment in time for which to return offsets, in
    248      * units of milliseconds from January 1, 1970 0:00 GMT, either GMT
    249      * time or local wall time, depending on `local'.
    250      * @param local if true, `date' is local wall time; otherwise it
    251      * is in GMT time.
    252      * @param rawOffset output parameter to receive the raw offset, that
    253      * is, the offset not including DST adjustments
    254      * @param dstOffset output parameter to receive the DST offset,
    255      * that is, the offset to be added to `rawOffset' to obtain the
    256      * total offset between local and GMT time. If DST is not in
    257      * effect, this value is zero; otherwise it is a positive value,
    258      * typically one hour.
    259      * @param ec input-output error code
    260      * @stable ICU 3.8
    261      */
    262     virtual void getOffset(UDate date, UBool local, int32_t& rawOffset,
    263                            int32_t& dstOffset, UErrorCode& ec) const;
    264 
    265     /**
    266      * Sets the TimeZone's raw GMT offset (i.e., the number of milliseconds to add
    267      * to GMT to get local time, before taking daylight savings time into account).
    268      *
    269      * @param offsetMillis  The new raw GMT offset for this time zone.
    270      * @stable ICU 3.8
    271      */
    272     virtual void setRawOffset(int32_t offsetMillis);
    273 
    274     /**
    275      * Returns the TimeZone's raw GMT offset (i.e., the number of milliseconds to add
    276      * to GMT to get local time, before taking daylight savings time into account).
    277      *
    278      * @return   The TimeZone's raw GMT offset.
    279      * @stable ICU 3.8
    280      */
    281     virtual int32_t getRawOffset(void) const;
    282 
    283     /**
    284      * Queries if this time zone uses daylight savings time.
    285      * @return true if this time zone uses daylight savings time,
    286      * false, otherwise.
    287      * @stable ICU 3.8
    288      */
    289     virtual UBool useDaylightTime(void) const;
    290 
    291     /**
    292      * Queries if the given date is in daylight savings time in
    293      * this time zone.
    294      * This method is wasteful since it creates a new GregorianCalendar and
    295      * deletes it each time it is called. This is a deprecated method
    296      * and provided only for Java compatibility.
    297      *
    298      * @param date the given UDate.
    299      * @param status Output param filled in with success/error code.
    300      * @return true if the given date is in daylight savings time,
    301      * false, otherwise.
    302      * @deprecated ICU 2.4. Use Calendar::inDaylightTime() instead.
    303      */
    304     virtual UBool inDaylightTime(UDate date, UErrorCode& status) const;
    305 
    306     /**
    307      * Returns true if this zone has the same rule and offset as another zone.
    308      * That is, if this zone differs only in ID, if at all.
    309      * @param other the <code>TimeZone</code> object to be compared with
    310      * @return true if the given zone is the same as this one,
    311      * with the possible exception of the ID
    312      * @stable ICU 3.8
    313      */
    314     virtual UBool hasSameRules(const TimeZone& other) const;
    315 
    316     /**
    317      * Gets the first time zone transition after the base time.
    318      * @param base      The base time.
    319      * @param inclusive Whether the base time is inclusive or not.
    320      * @param result    Receives the first transition after the base time.
    321      * @return  TRUE if the transition is found.
    322      * @stable ICU 3.8
    323      */
    324     virtual UBool getNextTransition(UDate base, UBool inclusive, TimeZoneTransition& result) const;
    325 
    326     /**
    327      * Gets the most recent time zone transition before the base time.
    328      * @param base      The base time.
    329      * @param inclusive Whether the base time is inclusive or not.
    330      * @param result    Receives the most recent transition before the base time.
    331      * @return  TRUE if the transition is found.
    332      * @stable ICU 3.8
    333      */
    334     virtual UBool getPreviousTransition(UDate base, UBool inclusive, TimeZoneTransition& result) const;
    335 
    336     /**
    337      * Returns the number of <code>TimeZoneRule</code>s which represents time transitions,
    338      * for this time zone, that is, all <code>TimeZoneRule</code>s for this time zone except
    339      * <code>InitialTimeZoneRule</code>.  The return value range is 0 or any positive value.
    340      * @param status    Receives error status code.
    341      * @return The number of <code>TimeZoneRule</code>s representing time transitions.
    342      * @stable ICU 3.8
    343      */
    344     virtual int32_t countTransitionRules(UErrorCode& status) const;
    345 
    346     /**
    347      * Gets the <code>InitialTimeZoneRule</code> and the set of <code>TimeZoneRule</code>
    348      * which represent time transitions for this time zone.  On successful return,
    349      * the argument initial points to non-NULL <code>InitialTimeZoneRule</code> and
    350      * the array trsrules is filled with 0 or multiple <code>TimeZoneRule</code>
    351      * instances up to the size specified by trscount.  The results are referencing the
    352      * rule instance held by this time zone instance.  Therefore, after this time zone
    353      * is destructed, they are no longer available.
    354      * @param initial       Receives the initial timezone rule
    355      * @param trsrules      Receives the timezone transition rules
    356      * @param trscount      On input, specify the size of the array 'transitions' receiving
    357      *                      the timezone transition rules.  On output, actual number of
    358      *                      rules filled in the array will be set.
    359      * @param status        Receives error status code.
    360      * @stable ICU 3.8
    361      */
    362     virtual void getTimeZoneRules(const InitialTimeZoneRule*& initial,
    363         const TimeZoneRule* trsrules[], int32_t& trscount, UErrorCode& status) const;
    364 
    365 private:
    366     enum { DEFAULT_VTIMEZONE_LINES = 100 };
    367 
    368     /**
    369      * Default constructor.
    370      */
    371     VTimeZone();
    372     static VTimeZone* createVTimeZone(VTZReader* reader);
    373     void write(VTZWriter& writer, UErrorCode& status) const;
    374     void write(UDate start, VTZWriter& writer, UErrorCode& status) const;
    375     void writeSimple(UDate time, VTZWriter& writer, UErrorCode& status) const;
    376     void load(VTZReader& reader, UErrorCode& status);
    377     void parse(UErrorCode& status);
    378 
    379     void writeZone(VTZWriter& w, BasicTimeZone& basictz, UVector* customProps,
    380         UErrorCode& status) const;
    381 
    382     void writeHeaders(VTZWriter& w, UErrorCode& status) const;
    383     void writeFooter(VTZWriter& writer, UErrorCode& status) const;
    384 
    385     void writeZonePropsByTime(VTZWriter& writer, UBool isDst, const UnicodeString& zonename,
    386                               int32_t fromOffset, int32_t toOffset, UDate time, UBool withRDATE,
    387                               UErrorCode& status) const;
    388     void writeZonePropsByDOM(VTZWriter& writer, UBool isDst, const UnicodeString& zonename,
    389                              int32_t fromOffset, int32_t toOffset,
    390                              int32_t month, int32_t dayOfMonth, UDate startTime, UDate untilTime,
    391                              UErrorCode& status) const;
    392     void writeZonePropsByDOW(VTZWriter& writer, UBool isDst, const UnicodeString& zonename,
    393                              int32_t fromOffset, int32_t toOffset,
    394                              int32_t month, int32_t weekInMonth, int32_t dayOfWeek,
    395                              UDate startTime, UDate untilTime, UErrorCode& status) const;
    396     void writeZonePropsByDOW_GEQ_DOM(VTZWriter& writer, UBool isDst, const UnicodeString& zonename,
    397                                      int32_t fromOffset, int32_t toOffset,
    398                                      int32_t month, int32_t dayOfMonth, int32_t dayOfWeek,
    399                                      UDate startTime, UDate untilTime, UErrorCode& status) const;
    400     void writeZonePropsByDOW_GEQ_DOM_sub(VTZWriter& writer, int32_t month, int32_t dayOfMonth,
    401                                          int32_t dayOfWeek, int32_t numDays,
    402                                          UDate untilTime, int32_t fromOffset, UErrorCode& status) const;
    403     void writeZonePropsByDOW_LEQ_DOM(VTZWriter& writer, UBool isDst, const UnicodeString& zonename,
    404                                      int32_t fromOffset, int32_t toOffset,
    405                                      int32_t month, int32_t dayOfMonth, int32_t dayOfWeek,
    406                                      UDate startTime, UDate untilTime, UErrorCode& status) const;
    407     void writeFinalRule(VTZWriter& writer, UBool isDst, const AnnualTimeZoneRule* rule,
    408                         int32_t fromRawOffset, int32_t fromDSTSavings,
    409                         UDate startTime, UErrorCode& status) const;
    410 
    411     void beginZoneProps(VTZWriter& writer, UBool isDst, const UnicodeString& zonename,
    412                         int32_t fromOffset, int32_t toOffset, UDate startTime, UErrorCode& status) const;
    413     void endZoneProps(VTZWriter& writer, UBool isDst, UErrorCode& status) const;
    414     void beginRRULE(VTZWriter& writer, int32_t month, UErrorCode& status) const;
    415     void appendUNTIL(VTZWriter& writer, const UnicodeString& until, UErrorCode& status) const;
    416 
    417     BasicTimeZone   *tz;
    418     UVector         *vtzlines;
    419     UnicodeString   tzurl;
    420     UDate           lastmod;
    421     UnicodeString   olsonzid;
    422     UnicodeString   icutzver;
    423 
    424 public:
    425     /**
    426      * Return the class ID for this class. This is useful only for comparing to
    427      * a return value from getDynamicClassID(). For example:
    428      * <pre>
    429      * .   Base* polymorphic_pointer = createPolymorphicObject();
    430      * .   if (polymorphic_pointer->getDynamicClassID() ==
    431      * .       erived::getStaticClassID()) ...
    432      * </pre>
    433      * @return          The class ID for all objects of this class.
    434      * @stable ICU 3.8
    435      */
    436     static UClassID U_EXPORT2 getStaticClassID(void);
    437 
    438     /**
    439      * Returns a unique class ID POLYMORPHICALLY. Pure virtual override. This
    440      * method is to implement a simple version of RTTI, since not all C++
    441      * compilers support genuine RTTI. Polymorphic operator==() and clone()
    442      * methods call this method.
    443      *
    444      * @return          The class ID for this object. All objects of a
    445      *                  given class have the same class ID.  Objects of
    446      *                  other classes have different class IDs.
    447      * @stable ICU 3.8
    448      */
    449     virtual UClassID getDynamicClassID(void) const;
    450 };
    451 
    452 U_NAMESPACE_END
    453 
    454 #endif /* #if !UCONFIG_NO_FORMATTING */
    455 
    456 #endif // VTZONE_H
    457 //eof
    458