Boost logo

Boost :

From: Jeff Garland (jeff_at_[hidden])
Date: 2003-12-25 08:10:59


On Wed, 24 Dec 2003 21:08:31 -0500, Kirill Lapshin wrote
> Anyways, the main source of my confusion is that all time zone
> adjuster classes implemented as templates accepting timezone traits
> as template arguments. The problem with this approach is that it is
> hard to deal with different time zones at runtime, since various
> time zones represented with various types. When program is written
> it is usually not known in advance what time zone it is going to be
> used in. Partially this problem could be solved with

I agree. I wrote the compile-time code as an experiment to see how well it
would work and to flesh out the underlying conversion functions.

> c_local_time_adjuster, only partially because it provides one-way
> conversion only, it works for narrow subset of all times (only those
> supported by time_t), and works only for local time zone. Dealing
> with few time zones simultaneously is quite problematic.

Agreed. An extremely useful, but limited solution.

> Ideally I would love to see a single adjuster class supporting all
> time zones at run time, rather than compile time. It would be great
> to have function capable of parsing POSIX time zone definition (e.g.,
> TZ env variable format).

As it turns out we have been working exactly toward this goal. This feature
won't be checked in until sometime after the 1.31 release. Here is the
synopsis of the posix time zone class which holds various strings, dst rules,
and offset from UTC.

  //! A time zone class constructed from a POSIX time zone string
  /*! A POSIX time zone string takes to form of:<br>
   * "std offset dst [offset],start[/time],end[/time]" (w/no spaces)
   * 'std' specifies the abbrev of the time zone.<br>
   * 'offset' is the offset from UTC.<br>
   * 'dst' specifies the abbrev of the time zone during daylight savings time.<br>
   * The second offset is how many hours changed during DST. Default=1<br>
   * 'start' & 'end' are the dates when DST goes into (and out of) effect.<br>
   * 'offset' takes the form of: [+|-]hh[:mm[:ss]] {h=0-23, m/s=0-59}<br>
   * 'time' and 'offset' take the same form. Time defaults=02:00:00<br>
   * 'start' & 'end' can be one of three forms:<br>
   * Mm.w.d {month=1-12, week=1-5 (5 is always last), day=0-6}<br>
   * Jn {n=1-365 Feb29 is never counted}<br>
   * n {n=0-365 Feb29 is counted in leap years}<br>
   * Example "PST-5PDT01:00:00,M4.1.0/02:00:00,M10.1.0/02:00:00"
   * <br>
   * Exceptions will be thrown under these conditions:<br>
   * An invalid date spec (see date class)<br>
   * A boost::local_time::bad_offset exception will be thrown for:<br>
   * A DST start or end offset that is negative or more than 24 hours<br>
   * A UTC zone that is greater than +12 or less than -12 hours<br>
   * A boost::local_time::bad_adjustment exception will be thrown for:<br>
   * A DST adjustment that is 24 hours or more (positive or negative)<br>
   */
  class posix_time_zone : public time_zone_base {
  public:
    typedef boost::posix_time::time_duration time_duration_type;
    typedef boost::tokenizer<boost::char_separator<char> > tokenizer;

   //! Construct from a POSIX time zone string
    posix_time_zone(const std::string& s);
    virtual ~posix_time_zone() {};
    //!String for the zone when not in daylight savings (eg: EST)
    virtual std::string std_zone_abbrev()const;
    //!String for the timezone when in daylight savings (eg: EDT)
    virtual std::string dst_zone_abbrev() const;
    //!String for the zone when not in daylight savings (eg: Eastern Standard
Time)
    virtual std::string std_zone_name()const;
    //!String for the timezone when in daylight savings (eg: Eastern Daylight
Time)
    virtual std::string dst_zone_name()const;
    //! True if zone uses daylight savings adjustments otherwise false
    virtual bool has_dst()const;
    //! Local time that DST starts -- undefined if has_dst is false
    virtual posix_time::ptime dst_local_start_time(gregorian::greg_year y)const;
    //! Local time that DST ends -- undefined if has_dst is false
    virtual posix_time::ptime dst_local_end_time(gregorian::greg_year y)const;
    //! Base offset from UTC for zone (eg: -07:30:00)
    virtual time_duration_type base_utc_offset()const;
    //! Adjustment forward or back made while DST is in effect
    virtual time_duration_type dst_offset()const;

> Also it would be nice to be able to tell
> what the local time zone is, using platform specific functionality.
> This could be tricky -- I still have no idea what the right way to
> do this on *nix -- standard POSIX daylight, timezone, and tzname
> variables do not provide information on when DST starts and ends. On

You would have to build up an internal map to match zone names in rules. Or
if you follow the guidelines in the reference below you will be able to
specify the DST rules and the new timezone class will be able to interpret them.

http://www.gnu.org/manual/glibc-2.0.6/html_chapter/libc_17.html#SEC303

> windows, there is a Win API function GetTimeZoneInformation. Dealing
> with platform specific definitions might be out of library scope though.

The goal is portability. Of course you could set a POSIX timezone environment
variable on your Windows machine for a program to read. Also, the new
timezone code has a base class that abstracts the timezone information and
could be used to write portable code with derived windows timezone class as
well as the POSIX timezone class. Or even with something that wraps up the
timezone db which has a geographical specification of zones.

Unfortunately, this stuff won't be in the library until Jan...

HTH,

Jeff


Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk