2

I'm struggling to figure out how to preform a conversion with boost::date_time. I want to convert a millisecond value measured from the Unix epoch (00:00, Jan 1, 1970) to a human readable string - something like: 2/13/2012 15:20:11 would be ideal.

I've tried some std C++ / boost suggestions I've seen but not had any luck just yet. Here is the code I use:

    long long ticksFromEpoch = 1329117220501;

    std::time_t tt = static_cast<time_t>(ticksFromEpoch);

    boost::posix_time::ptime dt = boost::posix_time::from_time_t(tt);

    // Create a time_zone_ptr for the desired time zone and use it to create a local_date_time
    boost::local_time::time_zone_ptr zone(new boost::local_time::posix_time_zone("UTC"));
    boost::local_time::local_date_time dt_with_zone(dt, zone);

    std::stringstream strm;

    strm.imbue(std::locale(std::cout.getloc(), new boost::local_time::local_time_facet("%Y-%m-%d %H:%M:%S"))); // 15:14
    strm << dt_with_zone;

    // Print the stream's content to the console
    std::cout << strm.str() << std::endl;

The output is: 2032-07-01 20:20:37 which is clearly incorrect. I suspect that I'm not constructing the ticksFromEpoch variable correctly but I'm not sure why. Can anyone point me in the right direction? Any help is much appreciated!!

Pat Mustard
  • 1,852
  • 9
  • 31
  • 58
  • 1
    Boost solution for Windows and posix posted [here][1] [1]: http://stackoverflow.com/questions/8916071/converting-datetime-to-different-timezone-in-c-boost/9274998#9274998 – Pat Mustard Feb 14 '12 at 23:27

1 Answers1

7

time_t is usually seconds since "the epoch", rather than milliseconds. If you dont care about milliseconds you should be able to do this:

std::time_t tt = static_cast<time_t>(ticksFromEpoch/1000)

If you do care about milliseconds you can either add them back in at the end (which is tricky to get right for times like 12:00:00.001 AM )

Or you'll need to go another route. You may need to use something like this: (untested)

boost::posix_time::ptime t2(
  boost::gregorian::date(1970,boost::date_time::Jan,1),  //The epoch
  boost::posix_time::seconds( ticksFromEpoch / 1000 ) + // Number of seconds
  boost::posix_time::milliseconds( ticksFromEpoch % 1000)  // And the micros too.
  );
csg
  • 8,096
  • 3
  • 14
  • 38
Michael Anderson
  • 70,661
  • 7
  • 134
  • 187
  • Thanks for the quick response, Michael! Your initial observation worked. almost. `std::time_t tt = static_cast(ticksFromEpoch/1000);` but the result still seems to be 8 hours behind my locale. – Pat Mustard Feb 13 '12 at 08:42
  • 2
    @Frank, your ticks must be UTC ticks then (which is correct for posix time). Switch to local time using the timezone functions found here: http://www.boost.org/doc/libs/1_48_0/doc/html/date_time/local_time.html – Michael Anderson Feb 13 '12 at 09:01
  • Again thank you for your input! Perhaps I don't understand the docs correctly but it seems that I need to specify the timezone explicitly with something like `"MST-07"` whereas I am looking for something that deduces the timezone it lives in dynamically as my system will run in a number of different timezones. – Pat Mustard Feb 13 '12 at 09:30
  • In order to dynamically deduce the timezone I had to use the following C code: `time_t now = time(NULL); struct tm tnow = *localtime(&now);//gmtime(&now); char buff[100]; strftime( buff, sizeof buff, "%a %b %d %Y %T %Z%z", &tnow ); printf( ">>%s<<\n", buff );` which does get the system timezone required. Cheers... – Pat Mustard Feb 13 '12 at 13:26