Re: [boost] [date_time] Time zone improvements

Jeff Garland wrote:
Very cool :-) One question -- is there a portable solution where a user could deploy a files onto a Windows system or is it a Unix only solution?
Portable, big endian binary files. The variant I'm proposing is also based on the POSIX standard http://www.opengroup.org/onlinepubs/000095399/basedefs/xbd_chap08.html: "TZ This variable shall represent timezone information. The contents of the environment variable named TZ shall be used by the [snip] functions, and by various utilities, to override the default timezone. The value of TZ has one of the two forms (spaces inserted for clarity): :characters or: std offset dst offset, rule " The second variant is what's currently in Boost.Date_Time as Posix Time Zone, having a direct specification of the time zone. I'll be talking about the first variant, containing :characters. Although this is implementaiton specific, most POSIX-compatible systems have implemented the Zoneinfo database for this variant, e.g., Linux-based systems, many BSDs, Mac OS X, etc. The :characters point to any other zoneinfo-compatible binary file, either with an absolute or relative path. A natural step for changing Boost.Date_Time would be to make changes such that the Posix Time Zone supports both formats. I.e., variant 1) posix_time_zone( ":/etc/localtime" ); or posix_time_zone( ":/usr/share/zoneinfo/Europe/Amsterdam" ); variant 2) posix_time_zone( "EST-5EDT,M4.1.0,M10.5.0" ); I think both should work as it is from the same standard, and seems to be a natural and consistent starting point to look at changing the interface. Do you agree?
Actually, I believe the abstract timezone is able to support this, but there isn't a concrete implementation. It would be great to have the concrete implementation to prove out the abstraction (obviously from the text below you think there needs to be changes).
As far as I can tell, the abstract time zone class currently is not able to represent variant 1): the abstract zone class is geared towards a single-lined definition of a time zone, whereas variant 1) may be regarded as a series of definitions, i.e., a map of < transition_time_point_in_utc, { gmt_offset, abbreviation, is_dst, ... } > looking up utc_to_local is a matter of doing a lower_bound search on the transition time points. The right-hand side of the map above is widely implemented with a struct called ttinfo. A proposal from my side would be to change the abstract time zone class in such way that it is able to represent both variants. The easiest approach here is probably to introduce the ttinfo structure, and make the current library working with that. variant 1): has a map of transition points, returns a (pointer to a) ttinfo structure. May hold more than 2 different ttinfo structures. variant 2): always has 2 ttinfo structures (std/dst). Uses dst-calculations/functions to lookup the transitions point, returns the right (pointer to a) ttinfo structure. What do you think? Cheers, Rutger

Rutger ter Borg wrote:
Jeff Garland wrote:
This thread is in slow motion...but keeping it going...
Very cool :-) One question -- is there a portable solution where a user could deploy a files onto a Windows system or is it a Unix only solution?
Portable, big endian binary files.
The variant I'm proposing is also based on the POSIX standard http://www.opengroup.org/onlinepubs/000095399/basedefs/xbd_chap08.html:
Ok.
"TZ This variable shall represent timezone information. The contents of the environment variable named TZ shall be used by the [snip] functions, and by various utilities, to override the default timezone. The value of TZ has one of the two forms (spaces inserted for clarity): :characters or: std offset dst offset, rule "
Ok.
The second variant is what's currently in Boost.Date_Time as Posix Time Zone, having a direct specification of the time zone. I'll be talking about the first variant, containing :characters. Although this is implementaiton specific, most POSIX-compatible systems have implemented the Zoneinfo database for this variant, e.g., Linux-based systems, many BSDs, Mac OS X, etc. The :characters point to any other zoneinfo-compatible binary file, either with an absolute or relative path.
A natural step for changing Boost.Date_Time would be to make changes such that the Posix Time Zone supports both formats. I.e.,
variant 1) posix_time_zone( ":/etc/localtime" ); or posix_time_zone( ":/usr/share/zoneinfo/Europe/Amsterdam" ); variant 2) posix_time_zone( "EST-5EDT,M4.1.0,M10.5.0" );
I think both should work as it is from the same standard, and seems to be a natural and consistent starting point to look at changing the interface. Do you agree?
Ok, again it would be wonderful if this could also be deployed to a properly configure Windows system -- preferably without changing the string.
Actually, I believe the abstract timezone is able to support this, but there isn't a concrete implementation. It would be great to have the concrete implementation to prove out the abstraction (obviously from the text below you think there needs to be changes).
As far as I can tell, the abstract time zone class currently is not able to represent variant 1): the abstract zone class is geared towards a single-lined definition of a time zone, whereas variant 1) may be regarded as a series of definitions, i.e., a map of
< transition_time_point_in_utc, { gmt_offset, abbreviation, is_dst, ... } >
looking up utc_to_local is a matter of doing a lower_bound search on the transition time points.
Look carefully at the abstract time zone. It's designed so that when you ask for the local_start_time and the local_end_time for dst you need to provide the year as a parameter so that subclasses can provide the historic conversions -- so it looks like this: time_zone_base tz = ... ptime t = tz.dst_local_start_time(2008); But, it's possible that to fully support support Olsen you'll need dst_offset and maybe some others to be expanded to support a year parameter as well. In any case I think we should be able to do that in a backward compatible fashion.
The right-hand side of the map above is widely implemented with a struct called ttinfo.
A proposal from my side would be to change the abstract time zone class in such way that it is able to represent both variants. The easiest approach here is probably to introduce the ttinfo structure, and make the current library working with that.
variant 1): has a map of transition points, returns a (pointer to a) ttinfo structure. May hold more than 2 different ttinfo structures.
variant 2): always has 2 ttinfo structures (std/dst). Uses dst-calculations/functions to lookup the transitions point, returns the right (pointer to a) ttinfo structure.
What do you think?
At first blush, I'd like to make as few changes to the abstract timezone as possible and would prefer to simply add a new subclass, but I'll keep an open mind as we work thru the details. Jeff

Jeff Garland wrote:
This thread is in slow motion...but keeping it going...
Yes.
Ok, again it would be wonderful if this could also be deployed to a properly configure Windows system -- preferably without changing the string.
My examples are using absolute path names. It should also work for relative path names, so we could say posix_time_zone( ":America/New_York" ), or posix_time_zone( ":localtime" ) for the system's local time zone (which is just a symlink to the local time zone). What it would require is a default path for the zoneinfo files, e.g., under most posix systems these zone definitions are in /usr/share/zoneinfo/. For Windows-based systems, we would have to figure out a reasonable and/or default.
Look carefully at the abstract time zone. It's designed so that when you ask for the local_start_time and the local_end_time for dst you need to provide the year as a parameter so that subclasses can provide the historic conversions -- so it looks like this:
time_zone_base tz = ... ptime t = tz.dst_local_start_time(2008);
But, it's possible that to fully support support Olsen you'll need dst_offset and maybe some others to be expanded to support a year parameter as well. In any case I think we should be able to do that in a backward compatible fashion.
That is under the assumption that a year has exactly two transition points -- which is false for a number of historic cases. This sometimes occurred when a locality switched time zone rules. Take the example of Europe/Amsterdam, where there have been three transitions in 1937, see below. $ date -d "19370201" Mon Feb 1 00:00:00 AMT 1937 $ date -d "19370801" Sun Aug 1 00:00:00 NEST 1937 $ date -d "19371101" Mon Nov 1 00:00:00 NET 1937
At first blush, I'd like to make as few changes to the abstract timezone as possible and would prefer to simply add a new subclass, but I'll keep an open mind as we work thru the details.
Here's where the more difficult part comes, I think we have two options: * We modify the abstract time zone in such way that it has a superset of its current capabilities, covering both POSIX timezone variant requirements. * We do a run-time selection of timezone base, selecting one of the implementations of both POSIX-variants. I am probably in favour of the first option, given that we don't change the posix_time_zone interface itself, and most work will be under the hood for hopefully a larger part of the current userbase. Cheers, Rutger

On Monday 01 December 2008, Jeff Garland wrote:
A natural step for changing Boost.Date_Time would be to make changes such that the Posix Time Zone supports both formats. I.e.,
variant 1) posix_time_zone( ":/etc/localtime" ); or posix_time_zone( ":/usr/share/zoneinfo/Europe/Amsterdam" ); variant 2) posix_time_zone( "EST-5EDT,M4.1.0,M10.5.0" );
I think both should work as it is from the same standard, and seems to be a natural and consistent starting point to look at changing the interface. Do you agree?
Ok, again it would be wonderful if this could also be deployed to a properly configure Windows system -- preferably without changing the string.
Yes, the zones can be defined without a full path, e.g., "localtime" and "Europe/Amsterdam". For timezone information available on Windows systems, there's a mapping from Windows timezone IDs to the standard TZIDs available here, http://www.unicode.org/cldr/data/charts/supplemental/windows_tzid.html, we could use the reverse of this mapping. E.g., "America/New_York" -> "Eastern Standard Time", etc. for a native windows implementation. For more Windows-related timezone stuff I found the following link informative, http://tinyurl.com/26tp5e. Apparently there's support for "Dynamic Timezone Information" in Windows as of Vista.
At first blush, I'd like to make as few changes to the abstract timezone as possible and would prefer to simply add a new subclass, but I'll keep an open mind as we work thru the details.
Let's pick up where we left, Cheers, Rutger
participants (2)
-
Jeff Garland
-
Rutger ter Borg