13

I need to convert double with number of seconds since the epoch to ptime. I'm prety sure there must be an easy way to do this, but I couldn't find anything. Thanks.

Edit: The original timestamp is floating point. I can't change it and i don't want to lose the sub-second precision.

cube
  • 3,867
  • 7
  • 32
  • 52
  • You sure you need a double? I think it fits in a int. – slipbull Jul 22 '09 at 19:30
  • 1
    Yes, I need double -- it's a part of an interface that I can't change. If it's a number of seconds then you can't capture the fractional part ... and http://xkcd.com/607/ :-) – cube Jul 22 '09 at 19:50

3 Answers3

8

Use the from_time_t() conversion function. A time_t is a UNIX timestamp, i.e. the number of seconds since the epoch.

John Kugelman
  • 349,597
  • 67
  • 533
  • 578
8

For a machine that has boost date/time compiled to the default level of microsecond resolution, try this:

double ts = 1250524800.5;
// Use floor() here if seconds are always positive.
time_t secondsSinceEpoch = floor(ts);
long microsecondsSinceSecond =
    floor((ts - static_cast<double>(secondsSinceEpoch)) * 1000000);
boost::posix_time::ptime result =
    boost::posix_time::from_time_t(secondsSinceEpoch);
boost::posix_time::time_duration fractionalSeconds(0, 0, 0,
                                                   microsecondsSinceSecond);
result += fractionalSeconds;
cout << "Time stamp is " << result << endl;

The output for this is "Time stamp is 2009-Aug-17 16:00:00.500000" on my linux box.

BD at Rivenhill
  • 12,395
  • 10
  • 46
  • 49
  • 2
    You probably want to add a `+0.5` to your `microsecondsSinceSecond` calculation to get round-to-nearest. Otherwise you'll suffer from truncation bugs. Though... I guess anybody who cares about the difference of a half of a microsecond probably wouldn't store a timestamp in a `double` in the first place. – Tom Feb 10 '10 at 04:38
  • @Tom: You are correct here, although I expect that anyone who really cares about this level of resolution will configure their Boost distribution for nanosecond support and make appropriate changes to the code above. – BD at Rivenhill Feb 10 '10 at 21:45
7

after some fiddling around i came up with this:

ptime(date(1970, 1, 1), time_duration(0, 0, 0, time_duration::ticks_per_second() * 1234567890.0987654321))

I'm not sure this is the best solution, but it seems to do what i need.

cube
  • 3,867
  • 7
  • 32
  • 52
  • Actually this is the best solution, because it doesn't assume that time_t is based on 1970-01-01. (Although maybe it could be split over a couple of lines :-) ) – Arthur Tacca Mar 06 '19 at 08:23