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