[Boost-users] [DateTime] from time_t to ptime and back - or not

1,583 views
Skip to first unread message

Christoph Duelli

unread,
Aug 20, 2010, 11:23:15 AM8/20/10
to boost...@lists.boost.org
[I am using Boost 1.43.0 on linux, gcc 4.4.1]

I am having trouble with date_time's ptime.
I am passing it a time_t, and store that in a ptime object.
When I retrieve the time_t, I am getting a different value than the one I
passed to it originally.
(the difference seems to be 2 hours - in all probability due to UTC vs local
time issues).

Code:
time_t now = time(NULL);
boost::posix_time::ptime pt = boost::posix_time::from_time_t(now);
struct tm tm = to_tm(pt);
time_t should_be_now = mktime(&tm);
BOOST_CHECK_EQUAL(now, should_be_now);

fails for me: now is by 7200 seconds (i.e. 2 hours) ahead of.

Is this a bug in date_time or am I just failing to use it properly?


Thank you,
and best regards

Christoph

_______________________________________________
Boost-users mailing list
Boost...@lists.boost.org
http://lists.boost.org/mailman/listinfo.cgi/boost-users

John B. Turpish

unread,
Aug 22, 2010, 1:10:07 AM8/22/10
to boost...@lists.boost.org
On Fri, Aug 20, 2010 at 11:23 AM, Christoph Duelli <due...@melosgmbh.de> wrote:
> Code:
>  time_t now = time(NULL);
>  boost::posix_time::ptime pt = boost::posix_time::from_time_t(now);
>  struct tm tm = to_tm(pt);
>  time_t should_be_now = mktime(&tm);
>  BOOST_CHECK_EQUAL(now, should_be_now);
>
> fails for me: now is by 7200 seconds (i.e. 2 hours) ahead of.
>
> Is this a bug in date_time or am I just failing to use it properly?
>
I am by no means an expert, so take this with a grain of salt.
I would guess the problem is with your assumptions. The documentation
on to_tm (http://www.boost.org/doc/libs/1_44_0/doc/html/date_time/posix_time.html#ptime_struct_tm)
says nothing about timezones, and a ptime stores UTC, so I'd guess the
struct tm members would be set to what that point in time would be in
UTC. mktime, on the other hand, assumes the tm represents your local
time (http://cplusplus.com/reference/clibrary/ctime/mktime/).
Whether I'm right or wrong should be easily testable, especially for
you (since you know what timezone your PC is set to). Add to your
program a few output lines showing members of the tm and see if it
looks right for your local time.

Roland Bock

unread,
Aug 23, 2010, 4:08:29 AM8/23/10
to boost...@lists.boost.org

On 2010-08-20 17:23, Christoph Duelli wrote:
> [I am using Boost 1.43.0 on linux, gcc 4.4.1]
>
> I am having trouble with date_time's ptime.
> I am passing it a time_t, and store that in a ptime object.
> When I retrieve the time_t, I am getting a different value than the one I
> passed to it originally.
> (the difference seems to be 2 hours - in all probability due to UTC vs local
> time issues).
>
> Code:
> time_t now = time(NULL);
> boost::posix_time::ptime pt = boost::posix_time::from_time_t(now);
> struct tm tm = to_tm(pt);
> time_t should_be_now = mktime(&tm);
> BOOST_CHECK_EQUAL(now, should_be_now);
>
> fails for me: now is by 7200 seconds (i.e. 2 hours) ahead of.
>
> Is this a bug in date_time or am I just failing to use it properly?

Since struct tm is so weird, here is what I do:

boost::posix_time::ptime epoch(boost::gregorian::date(1970,1,1));
time_t also_now = (pt - epoch).total_seconds();


HTH

Roland

Christoph Duelli

unread,
Aug 23, 2010, 6:40:46 AM8/23/10
to boost...@lists.boost.org
John B. Turpish wrote:

Thank you.

> On Fri, Aug 20, 2010 at 11:23 AM, Christoph Duelli <due...@melosgmbh.de>
> wrote:
>> Code:
>> time_t now = time(NULL);
>> boost::posix_time::ptime pt = boost::posix_time::from_time_t(now);
>> struct tm tm = to_tm(pt);
>> time_t should_be_now = mktime(&tm);
>> BOOST_CHECK_EQUAL(now, should_be_now);
>>
>> fails for me: now is by 7200 seconds (i.e. 2 hours) ahead of.
>>
>> Is this a bug in date_time or am I just failing to use it properly?
>>
> I am by no means an expert, so take this with a grain of salt.

[snip]


> mktime, on the other hand, assumes the tm represents your local time
> (http://cplusplus.com/reference/clibrary/ctime/mktime/).

> Whether I'm right
> or wrong should be easily testable, especially for you (since you know

Yes, with t = time(0)
t == mktime(localtime(t))
but
t != mktime(gmtime(t))

> what timezone your PC is set to). Add to your program a few output lines
> showing members of the tm and see if it looks right for your local time.

However, that does not really help, because the struct tm that Boost ptime
produces is different from both gmtime and localtime:
DUMP gmtime
t.tm_sec=50
t.tm_min=31
t.tm_hour=9
t.tm_mday=23
t.tm_mon=7
t.tm_year=110
t.tm_wday=1
t.tm_yday=234
t.tm_isdst=0
t.tm_gmtoff=0
t.tm_zone=GMT
diff(time,mktime(gmtime(time)))=3600
DUMP localtime
t.tm_sec=50
t.tm_min=31
t.tm_hour=11
t.tm_mday=23
t.tm_mon=7
t.tm_year=110
t.tm_wday=1
t.tm_yday=234
t.tm_isdst=1
t.tm_gmtoff=7200
t.tm_zone=CEST
diff(time,mktime(localtime(time)))=0
DUMP boost from_time_t -> to_tm
t.tm_sec=50
t.tm_min=31
t.tm_hour=9
t.tm_mday=23
t.tm_mon=7
t.tm_year=110
t.tm_wday=1
t.tm_yday=234
t.tm_isdst=-1
t.tm_gmtoff=0
t.tm_zone=NULL
diff(time,mktime(to_tm(from_time_t(time))))=7200


It is not obvious how to fix the tm obtained from to_tm.
Probably it is easier to fix the resulting time_t.


I guess I will settle for the approach given in
http://lists.boost.org/boost-users/2007/07/29567.php
and stop using from_time_t and to_tm

Best regards
Christoph

Reply all
Reply to author
Forward
0 new messages