[Date_Time] Posix Time Zone offset question
Hi, I've started experimenting with Boost.Date_Time's Local Time stuff. While using a posix_time_zone object the results were not what I expected. I used the POSIX.1 (IEEE Std 1003.1) timezone string suitable for use in the TZ environment variable describing my timezone for the year 2006: MST7MDT,M4.1.0,M10.5.0 Date_Time's posix_time_zone object told me that it was already the 26th but my wall clock disagrees. :) The online documentation says "A posix_time_zone is unique in that the object is created from a Posix time zone string (IEEE Std 1003.1)." and "'offset' is the offset from UTC." In the sources I've come across the offset part of a POSIX.1 timezone string is defined as "the value added to the local time to arrive at Coordinated Universal Time" with a not that "[i]f preceded by a '-', the timezone shall be east of the Prime Meridian; otherwise, it shall be west (which may be indicated by an optional preceding '+' )." * http://www.opengroup.org/onlinepubs/000095399/basedefs/xbd_chap08.html * man pages of tzset Why do I need a negative (-) offset to make posix_time_zone work when the time zone is west of the Prime Meridian? I couldn't find anyone else raising this issue on the list or bug tracker, so maybe I'm just up in the night. Thank-you for the library. I really like some of the concepts in Date_Time Posix Time and Gregorian and have high hopes for Local Time stuff. -- Jacob
Jacob L. Anawalt wrote:
Hi,
I've started experimenting with Boost.Date_Time's Local Time stuff. While using a posix_time_zone object the results were not what I expected. I used the POSIX.1 (IEEE Std 1003.1) timezone string suitable for use in the TZ environment variable describing my timezone for the year 2006:
MST7MDT,M4.1.0,M10.5.0
Date_Time's posix_time_zone object told me that it was already the 26th but my wall clock disagrees. :)
The online documentation says "A posix_time_zone is unique in that the object is created from a Posix time zone string (IEEE Std 1003.1)." and "'offset' is the offset from UTC."
In the sources I've come across the offset part of a POSIX.1 timezone string is defined as "the value added to the local time to arrive at Coordinated Universal Time" with a not that "[i]f preceded by a '-', the timezone shall be east of the Prime Meridian; otherwise, it shall be west (which may be indicated by an optional preceding '+' )."
* http://www.opengroup.org/onlinepubs/000095399/basedefs/xbd_chap08.html * man pages of tzset
Why do I need a negative (-) offset to make posix_time_zone work when the time zone is west of the Prime Meridian?
Well, this is really just convention at some level. You might find this reference helpful: http://aa.usno.navy.mil/faq/docs/world_tzones.html It shows the offsets for various regions of the world.
I couldn't find anyone else raising this issue on the list or bug tracker, so maybe I'm just up in the night.
I'm not aware of any bugs in this code...
Thank-you for the library. I really like some of the concepts in Date_Time Posix Time and Gregorian and have high hopes for Local Time stuff.
My pleasure :-) Jeff
Jeff Garland wrote:
Well, this is really just convention at some level.
Right. POSIX.1 (IEEE Std 1003.1) convention as far as I am able to find. Unless I've found the wrong POSIX.1 documentation I consider the fact that posix_time_zone expects negative values for offsets west of the Prime Meridian or the fact that it claims to use IEEE Std 1003.1 timezone strings to be a bug. It would be nice to be able to use the TZ environment variable as the argument to the posix_time_zone constructor if TZ existed and did not have a leading colon. -- Jacob
Jacob Anawalt wrote:
Jeff Garland wrote:
Well, this is really just convention at some level.
Right. POSIX.1 (IEEE Std 1003.1) convention as far as I am able to find.
Sorry for the delayed response...travel and such. Well, I spoke a bit to losely, it isn't just convention it's in the spec.
Unless I've found the wrong POSIX.1 documentation I consider the fact that posix_time_zone expects negative values for offsets west of the Prime Meridian or the fact that it claims to use IEEE Std 1003.1 timezone strings to be a bug.
Anyway, if you go to http://www.unix.org/version3/ieee_std.html and register you can read the official spec. Here's the excerpt of the key parts: TZ This variable shall represent timezone information.... The expanded format (for all TZ s whose value does not have a colon as the first character) is as follows: stdoffset[dst[offset][,start[/time],end[/time]]] ... offset Indicates the value added to the local time to arrive at Coordinated Universal Time. The offset has the form: hh[:mm[:ss]] The minutes ( mm) and seconds ( ss) are optional. The hour ( hh) shall be required and may be a single digit. The offset following std shall be required .... If preceded by a '-', the timezone shall be east of the Prime Meridian; otherwise, it shall be west (which may be indicated by an optional preceding '+' ).
It would be nice to be able to use the TZ environment variable as the argument to the posix_time_zone constructor if TZ existed and did not l have a leading colon.
So, after staring at this spec for awhile, it looks to me that this is a major
bug in posix timezone :-( For whatever reason, posix has the utc offset
definitions inverted from the way it actually is...so you always have to
invert the sign of the offset to get the actual utc offset.
To be 100% sure, I'll need a bit more info. What OS are you using, what
timezone are you in, and what is TZ set to? Assuming it's unix, what do
'date' and 'date -u' give you?
And then what I assume you are doing exactly in date-time. Based on the first
email you sent I imagine it's something like:
shared_ptr
Jeff Garland wrote:
So, after staring at this spec for awhile, it looks to me that this is a major bug in posix timezone :-( For whatever reason, posix has the utc offset definitions inverted from the way it actually is...so you always have to invert the sign of the offset to get the actual utc offset.
I thought this was weird too, but that's how they spec'd it.
To be 100% sure, I'll need a bit more info. What OS are you using, what timezone are you in, and what is TZ set to? Assuming it's unix, what do 'date' and 'date -u' give you?
Debian 3.1 (GNU/Linux) America/Denver MST7MDT,M4.1.0,M10,5.0 (for 1987-2006) $ date Mon Oct 30 10:36:59 MST 2006 $ date -u Mon Oct 30 17:37:03 UTC 2006 $ TZ=MST7MDT,M4.1.0,M10,5.0 date Mon Oct 30 10:37:24 MST 2006 $ date --version date (coreutils) 5.2.1 Written by David MacKenzie. Copyright (C) 2004 Free Software Foundation, Inc. This is free software; see the source for copying conditions. There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
And then what I assume you are doing exactly in date-time. Based on the first email you sent I imagine it's something like:
shared_ptr
tz(new posix_time_zone("MST7MDT,M4.1.0,M10.5.0")); local_date_time ldt1 = local_sec_clock::local_time(tz);
Pretty much. This is some of my test code. namespace blt = boost::local_time; namespace bpt = boost::posix_time; bpt::ptime pt = bpt::second_clock::universal_time(); boost::shared_ptrblt::time_zone_base zone( new blt::posix_time_zone("MST7MDT,M4.1.0,M10.5.0")); blt::local_date_time ldt1(pt,zone); After familiarizing myself with the Local Time classes, my goal is to make a little wall time conversion program. Using the local_date_time class objects seems much cleaner and thread safe than messing with tzset (and thus the program's idea of the current TZ, tzname, timezone and daylight.) My TZ variable is normally empty and glibc looks at it's notion of the default zone in that case using the /usr/share/zoneinfo data. For now that's OK. The POSIX.1 spec says that if TZ is empty or starts with a colon, it's interpretation is implementation specific. My program's documented interpretation will be to default to UTC, so I'll have to run it with the right target TZ set if I want a different wall clock than UTC. Thank you for looking at this, -- Jacob
participants (3)
-
Jacob Anawalt
-
Jacob L. Anawalt
-
Jeff Garland