7

Is there a succinct way, or a generally accepted way to convert from a boost::posix_time::ptime to a mongo::Date_t and back again?

Mongo to Boost

The Boost documentation seems incomplete or incorrect. It documents a function date_from_tm which constructs a date struct from a tm. However, the following example is given:

tm pt_tm;
/* snip */
ptime pt = ptime_from_tm(pt_tm);

But there is no documented function ptime_from_tm. However this header file does include that function.

So, I can at least go from mongo::Date_t to boost::posix_time::ptime:

mongo::Date_t d = ...;
std::tm t;
d.toTm(&t);
boost::posix_time::ptime pt = ptime_from_tm(t);

Boost to Mongo

I'm kind of stuck when it comes to going in the opposite direction. The MongoDB documentation is rather incomplete, and the associated header file doesn't have many helpful comments. Basically, the Date_t struct is constructed from an unsigned long long millisecond count. I can only assume from the 1970-1-1:00:00.00 epoch.

So my current solution to go from a boost::posix_time::ptime to a mongo::Date_t is:

boost::posix_time::ptime pt = ...;
std::tm pt_tm = boost::posix_time::to_tm(pt);
std::time_t t = mktime(pt_tm);
mongo::Date_t d(t);

Of course, I can probably collapse that into one line, but it seems that the whole round trip from one date/time representation to the other and back again is becoming convoluted and messy.

Finally

Is there a better way? Does anybody with a better knowledge of both libraries and a good understanding of date/time programming know a succinct, simple way to achieve what I'm trying to achieve?

Anthony
  • 12,177
  • 9
  • 69
  • 105
  • [What have you tried?](http://mattgemmell.com/2008/12/08/what-have-you-tried/) – Some programmer dude Jun 11 '12 at 05:57
  • mktime(pt_tm) should be mktime(&pt_tm)? And do a conversion from ptime to Date_t, the result is incorrect. the ptime is "2011-10-28 23:30:30.000" but I get "Fri Jan 16 13:36:55 1970" in Date_t. mongo driver 2.4.3, boost 1530 – jean May 23 '13 at 08:18

2 Answers2

3

It seems your solution convert from ptime to Date_t has some problem, I try it and get incorrect result as I commented. I have a better way:

mongo::Date_t convert(const boost::posix_time::ptime& time)
{
    boost::posix_time::ptime epoch(boost::gregorian::date(1970,boost::date_time::Jan,1));
    boost::posix_time::time_duration d = time - epoch;
    return mongo::Date_t(d.total_milliseconds());
}
boost::posix_time::ptime convert(const mongo::Date_t& time)
{
    boost::posix_time::ptime epoch(boost::gregorian::date(1970,boost::date_time::Jan,1));
    boost::posix_time::time_duration d = boost::posix_time::milliseconds(time.millis);//- epoch;
    return boost::posix_time::ptime(epoch+d);
}

Notice that 2.4.3(as I know) Date_t::toString() has bug, the 'date' has been add 8 hours. You can verify 'total milliseconds' at here

jean
  • 2,825
  • 2
  • 35
  • 72
2

Basically, the Date_t struct is constructed from an unsigned long long millisecond count. I can only assume from the 1970-1-1:00:00.00 epoch.

You are correct.

I think your code is about as good as you're going to get. You have to somehow get to a time_t-like seconds-since-the epoch, which seems to be a little complex with ptime.

Community
  • 1
  • 1
kris
  • 23,024
  • 10
  • 70
  • 79