Opened 13 years ago
Last modified 9 years ago
#3336 new Bugs
utc offset calculated wrong
Reported by: | Owned by: | az_sw_dude | |
---|---|---|---|
Milestone: | Boost 1.57.0 | Component: | date_time |
Version: | Boost 1.54.0 | Severity: | Problem |
Keywords: | Cc: |
Description
Boost seems to invert the posix time zone specs or even worse to calculate them completely wrong:
http://www.opengroup.org/onlinepubs/000095399/basedefs/xbd_chap08.html
states:
"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 '+' )."
Using the following lines in a c++ program:
time_zone_ptr myzone(new posix_time_zone(string("CET-1CEST,M3.5.0,M10.5.0/3"))); // e.g. Europe/Berlin cout << "Posix time string: " << myzone->to_posix_string() << endl; local_date_time mylocaltime(date(2009,8,11), time_duration(17,0,0), myzone, true); cout << "Wall clock: " << mylocaltime.local_time() << endl; cout << "Time in UTC: " << mylocaltime.utc_time() << endl;
gives following output:
Posix time string: CET-01CEST+01,M3.5.0/02:00,M10.5.0/03:00
Wall clock: 2009-Aug-11 17:00:00
Time in UTC: 2009-Aug-11 17:00:00
The system I used: Debian GNU/Linux squeeze/sid
uname -a
Linux fafner 2.6.28.7 #1 SMP Mon Mar 16 17:39:15 CET 2009 i686 GNU/Linux
output from date:
date -d "2009-8-11 17:00 CEST "
Di 11. Aug 17:00:00 CEST 2009
date -d "2009-8-11 17:00 CEST " -u
Di 11. Aug 15:00:00 UTC 2009
Libraries (debian): libboost-date-time1.38.0 libboost-date-time1.38-dev libboost-date-time-dev
The time zone spec ist taken from /usr/share/zoneinfo/CET on my system.
Change History (5)
comment:1 by , 13 years ago
Component: | None → date_time |
---|---|
Owner: | set to |
comment:2 by , 12 years ago
comment:3 by , 10 years ago
Version: | Boost 1.38.0 → Boost 1.44.0 |
---|
This bug doesn't seem to get a lot of attention.
It is still valid for newer versions of the boost library.
comment:4 by , 9 years ago
Just got bitten by the same bug. Correct behavior:
$ export TZ="PST-8PDT,M3.2.0,M11.1.0"; date -d@1383465600 Sun Nov 3 16:00:00 PST 2013
posix_time_zone maps the same timestamp with the same timezone string to "Sun Nov 3 01:00:00 PST 2013" (16 hours - 1 DST adjustment). Here's another (currently working) link to the POSIX RFC that boost::local_time purports to implement:
http://tools.ietf.org/html/draft-ietf-dhc-timezone-01
The relevant text is at the end of page 2, beginning of page 3.
The boost::local_time documentation and code are both written assuming "-" means "west of Greenwich" and "+" means "east of Greenwich", but the standard clearly states otherwise.
Flipping the sign is pretty easy (I can send a patch, even), but I'm not sure what's Boost's preferred approach for fixing such errors. The flip would break code that depends on the currently broken behavior.
If it's not appropriate to fix the bug in the current API, posix_time_zone2 might be introduced that has the correct sign. Does anybody see other approaches?
comment:5 by , 9 years ago
Milestone: | Boost 1.40.0 → Boost 1.57.0 |
---|---|
Version: | Boost 1.44.0 → Boost 1.54.0 |
I reproduced it in 1.51 and 1.54.
The UTC offset in POSIX 1003.1 section 8.3 TZ strings is inverted from that in Olson TZ database strings, which is a cause for confusion. The former treats UTC as relative to the local time, i.e what do we add to the local wall clock to produce the wall clock time in UTC. The latter treats the local time as relative to UTC, as in, what do we add to the time in UTC to get to the local time.
The man pages for tzset(3) seem pretty consistent although some are clearer than others. I like this wording best, myself:
Sun is their own celestial body but they see it the same way:
http://docs.sun.com/source/816-5523-10/appf.htm
Here also, positive is west of Greenwich, negative is east of it.
As a hacky workaround, the string can be manipulated prior to feeding it to posix_time_zone. Find the first [0-9+-]. If we're not at the end of the string, if '+' change to '-' and vice versa. Otherwise insert '-' before the current position. Something like the following (untested!):