9

I'm trying to print a boost::posix_time::ptime in the format of "YYYY-MM-DD hh:mm:ss.fff" where the MM is a 2-digit month and fff a 3-digit millisecond. An example is: 2011-07-14 22:38:40.123.

I'm using Boost 1.33.1.

I tried to call the API "ptime::to_simple_string()" but it doesn't meet my need: this method prints the ptime in a format of "YYYY-MMM-DD hh:mm:ss.ffffff" where the "MMM" is a 3-char month name, such as "Jan", and "ffffff" is a 6-digit microsecond. This is NOT what I want.

I then tried to use the time_facet thing:

ptime my_time(second_clock::local_time());
time_facet<ptime, char> * my_time_facet = new time_facet<ptime, char>();
std::cout.imbue(std::locale(std::locale::classic(), my_time_facet));
std::cout << my_time;

But I got an output like "2011-07-14 22:38:40.123000". This is NOT what I want, either.

Looks like the ptime uses the microsecond as the time resolution by default. But I just need a millisecond resolution. After some study I think there could be two methods to solve this problem:

1). Somehow I can change the ptime's time resolution to use millisecond. I've found some enumation and template classes related to the time resolution but I don't know how to use them.

2). Somehow I can change my time facet format to print out just the millisecond. But the official documentation seems to say "%F" and "%f" both use the microsecond resolution.

I tend to prefer the first solution but I need help! How can I get a ptime string in the format I desire?

PS:

1). Though I've tried to search a similar question in this website but I don't find one. If you know it please tell me.

2). The Boost 1.33.1 Date Time documentation(http://www.boost.org/doc/libs/1_33_1/doc/html/date_time.html) is the only reference I've been reading.


Update on 07/15/2011:

After some further study, my conclusion is as follows:

1). It is possible to change the time resolution to millisecond so using the "%f" in a time_facet will print out just the milliseconds, instead of the default microseconds. However, you seems to need to define a whole suite of your own classes including your_time_res_traits, your_time_duration, your_time_system_config, your_time_system and your_time. This is definitely too complicated for my problem.

2). Thus I'd take Mark's suggestion(see below) to just strip out the last 3 chars after converting a microsecond-resolution ptime to a string.

zengr
  • 38,346
  • 37
  • 130
  • 192
yaobin
  • 2,436
  • 5
  • 33
  • 54
  • Out of curiosity, why are you using a nearly 6 year old version of Boost? – ildjarn Jul 14 '11 at 17:13
  • @ildjarn: Oh, because the 1.33.1 version is already in my hand so I don't want to bother upgrading to the latest version right now. That reminds me: Is there a nice solution in the latest Boost to solve my problem? Hm.. I'll go and take a look into the document.. – yaobin Jul 15 '11 at 00:05
  • Current versions of Boost.DateTime have microsecond resolution by default, which should more than suit your needs. But really, 6 years is **ancient** in C++ terms -- upgrade. – ildjarn Jul 15 '11 at 01:17

3 Answers3

5

The simple, pragmatic solution would be to use %f and always strip the last 3 characters from the result.

Mark Ransom
  • 299,747
  • 42
  • 398
  • 622
  • Yeah, I thought about this before :) But I think there should be a better way to directly output a ptime in the format I need. I'll wait on here and continue to search in the documentation. – yaobin Jul 15 '11 at 00:02
  • 1
    @rob, Define "better". There appears to be a way to write your own output conversion function, but it seems like overkill for such a simple problem. – Mark Ransom Jul 15 '11 at 02:48
  • Agree. After some further research I think the "strip" way should be the easiest :) – yaobin Jul 15 '11 at 10:23
1
//
// microsec_clock
//


  #include "boost/date_time/posix_time/posix_time.hpp"
  #include "boost/date_time/local_time_adjustor.hpp"
  #include "boost/date_time/c_local_time_adjustor.hpp"
  #include <iostream>
////////////////////////////////////////////////////////////////////////////////
void main ()
{
boost::posix_time::ptime my_time(boost::posix_time::microsec_clock::local_time());
boost::date_time::time_facet<boost::posix_time::ptime, char> * my_time_facet = new boost::date_time::time_facet<boost::posix_time::ptime, char>();
std::cout.imbue(std::locale(std::locale::classic(), my_time_facet));
std::cout << my_time;

getchar();
}
Jac08in
  • 19
  • 5
  • Soory, This answer does not give any solution.... will output microseconds.... not milliseconds. – Gabor Jun 10 '16 at 13:20
0

This will truncate the fractional seconds.

#include <iostream>
#include <iomanip>
#include <boost/date_time/gregorian/gregorian.hpp>
#include <boost/date_time.hpp>
#include <boost/date_time/posix_time/posix_time.hpp>

int main()
{
  boost::gregorian::date dayte(boost::gregorian::day_clock::local_day());
  boost::posix_time::ptime midnight(dayte);
  boost::posix_time::ptime
     now(boost::posix_time::microsec_clock::local_time());
  // boost::posix_time::time_duration td = now - midnight;
  boost::posix_time::time_duration td(1,2,3,4567899);

  std::stringstream sstream;
  sstream << td.fractional_seconds();

  std::string trunc = std::string(sstream.str()).substr(0,3);

  std::cout << dayte.year() << "-" << dayte.month().as_number()
    << "-" << dayte.day() << " ";
  std::cout << td.hours() << ":" << td.minutes() << ":" << td.seconds()
   << ":" << td.fractional_seconds() << std::endl;

  std::cout << std::endl;
  std::cout << std::setfill('0') << std::setw(2)  << td.hours() << ":";
  std::cout << std::setfill('0') << std::setw(2) << td.minutes() << ":";
  std::cout << std::setfill('0') << std::setw(2) << td.seconds() << ":";
  std::cout << trunc << std::endl;
}

Results

2015-10-27 1:2:7:567899

01:02:07:567
sfanjoy
  • 640
  • 6
  • 16