Boost logo

Boost :

From: Kirill Lapshin (kir_at_[hidden])
Date: 2003-12-24 21:08:31


Hello,

I've been happily using date_time library for a while now, but now I am
facing a time zone problem. Looking at what date_time can offer here
left me quite frustrated. Probably I am missing something obvious..

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 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.

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). 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 windows, there is a Win API
function GetTimeZoneInformation. Dealing with platform specific
definitions might be out of library scope though.

In meantime I created local_to_utc conversion using C locale. It can be
used as is to create a c_local_time_adjuster::local_to_utc. Feel free to
use it if you find it appropriate. Here is the code:

     date_type time_t_start_day(1970,1,1);
     time_type
time_t_start_time(time_t_start_day,time_duration_type(0,0,0));

     //not sure what is the earliest supported timestamp,
     //it differs from time zone to time zone...
     //maybe we should just call mktime unconditionally
     //and use it's return code to decide whether timestamp
     //supported or not.
     //for now let's user 01-Jan-1970 14:00
     //12 hours added since local time may be 12 hours
     //off UTC, plus 1 hour for DST, plus 1 just in case
     if (t < time_t_start_time+time_duration(14,0,0) ) {
         throw std::out_of_range("Cannot convert dates prior to Jan 1,
1970");
     }
     std::tm tms;
     tms.tm_year = t.date().year()-1900;
     tms.tm_mon = t.date().month()-1;
     tms.tm_mday = t.date().day();
     tms.tm_hour = t.time_of_day().hours();
     tms.tm_min = t.time_of_day().minutes();
     tms.tm_sec = t.time_of_day().seconds();
     tms.tm_isdst = -1; //let C library determine whether it dst or not

     time_t t2 = std::mktime(&tms);
     if (t2 == static_cast<time_t>(-1))
         throw std::out_of_range("Failed to convert local time to UTC.");

     return time_t_start_time
         + time_duration_type(0,0,t2,t.time_of_day().fractional_seconds());

--Kirill


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