21

I'm having trouble converting a ptime object from boost into a string to be passed in to a function. I have found multiple similar other threads in regards to outputing a boost time object to a string (mostly to cout) but none of what I've found on them are working.

It appears the easiest way is inserting the ptime object into a stringstream and then using the stringstream's string. I have also attempted to imbue the stringstream with a time_facet, as some of the answers on other threads suggest. However, I am unable to create a time_facet object. It gives me the error that the argument list for the class template is missing. What is confusing is the nowhere on the internet have I found any mention of an argument list for time_facet, and even boost's documentation page shows that the default constructor for a time_facet is merely time_facet().

Below is a simple version of what I have tried:

#include <boost/date_time/posix_time/posix_time.hpp>
#include <boost/date_time/posix_time/posix_time_io.hpp>

boost::posix_time::ptime time = boost::posix_time::time_from_string("1981-08-20 08:05:00"); 
std::stringstream sstream;
sstream << time;
_updateStatement->setString(1, (sql::SQLString)sstream.str());

The insertion of time into the stringstream gives me a bunch of compilation errors in the vein of

error C2220: warning treated as error - no 'object' file generated C:\code\trunk\Development\External\boost\include\boost/date_time/time_facet.hpp(247) :while compiling class template member function 'boost::date_time::time_facet<time_type,CharT>::time_facet(size_t)'
          with
          [
              time_type=boost::posix_time::ptime,
              CharT=char
          ]

despite the fact that I haven't used any time_facet objects.

When I DO try to do this with a time_facet object, I add in

sstream.imbue(std::locale(sstream.getloc(), new boost::date_time::time_facet("%Y-%m-%d %H:%M:%S")));

before inserting the time into the stringstream. The errors for that are that it wants an argument list as mentioned at the top of this post.

Is there perhaps a function in boost that is the reverse of boost::posix_time::time_from_string()? If not, any other help would be appreciated. Thank you.

user3517209
  • 213
  • 1
  • 2
  • 4

2 Answers2

31

The Boost.Date_Time library provides the following ptime to std::string conversions within the boost::posix_time namespace:

  • std::string to_simple_string(ptime) returns a string in the form of YYYY-mmm-DD HH:MM:SS.fffffffff format where mmm is the three character month name.
  • std::string to_iso_string(ptime) returns a string in the form of YYYYMMDDTHHMMSS,fffffffff where T is the date-time separator.
  • std::string to_iso_extended_string(ptime) returns a string in the form of YYYY-MM-DDTHH:MM:SS,fffffffff where T is the date-time separator.

Additionally, stream insertion and extraction operators are provided, allowing ptime to be inserted or extracted from a stream. The input and output formats can be customized by constructing facets with various format flags, and then imbuing the stream with the facet.

Based on the compile error (C2220), the compiler is set to treat all warnings as errors. In some cases, the Boost libraries will compile with warnings. Consider assessing the severity of the actual warning, and handling it appropriately from there. For example, if the warning is trivial, it may be acceptable to use a warning pragma to disable or suppress the specific warning.


Here is a complete example demonstrating converting ptime to a string via its provided conversion functions and stream operators.

#include <iostream>
#include <locale>
#include <string>
#include <boost/date_time/posix_time/posix_time.hpp>
#include <boost/date_time/posix_time/posix_time_io.hpp>

int main()
{
  const boost::posix_time::ptime time = 
      boost::posix_time::time_from_string("1981-08-20 08:05:00");

  // ptime to string.
  const std::string str_time = to_simple_string(time);
  std::cout << str_time << std::endl;

  // ptime to stringstream to string.
  std::stringstream stream;
  stream << time;
  std::cout << stream.str() << std::endl;
  stream.str("");

  // Use a facet to display time in a custom format (only hour and minutes).
  boost::posix_time::time_facet* facet = new boost::posix_time::time_facet();
  facet->format("%H:%M");
  stream.imbue(std::locale(std::locale::classic(), facet));
  stream << time;
  std::cout << stream.str() << std::endl;
}

Which produces the following output:

1981-Aug-20 08:05:00    
1981-Aug-20 08:05:00    
08:05
Tanner Sansbury
  • 51,153
  • 9
  • 112
  • 169
  • Yes, our project is set to regard all warnings as errors. While I'm still not sure why inserting the time into a stream and why creating time_facets are not working in my project (unless these always give warnings), the conversion functions of time to string seem to be doing the trick for me. Thank you very much! – user3517209 Apr 10 '14 at 14:13
  • Is there a way to add a "Z" at the end of the time? I have tried "%Y-%m-%dT%H%M%SZ" but I am getting just "YYYY-mm-ddTHH:MM:SS" and no Z at the end – sop Feb 25 '15 at 12:49
  • 3
    For those interested in why there's raw `new facet` and no `delete`: https://stackoverflow.com/questions/17779660/who-is-responsible-for-deleting-the-facet – Alex Che Sep 19 '19 at 10:24
  • ptime to stringstream to string worked for me. ptime to string didn't work. – csg Jul 30 '20 at 15:01
  • 1
    In which header and `namespace` is `to_simple_string` located? – mr5 Jul 01 '21 at 01:48
  • Example is not compilable `to_simple_string` is definately is not in a global namespace – Slava Apr 10 '23 at 18:55
6

My usage using release 1.55

#include <iostream>
#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;

  std::stringstream sstream;

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

  sstream << dayte << std::endl;
  sstream << dayte.year() << "/" << dayte.month().as_number()
     << "/" << dayte.day() << std::endl;
  sstream << now << std::endl;
  sstream << td << std::endl;
  sstream << td.hours() << "/" << td.minutes() << "/" << td.seconds()
    << "/" << td.fractional_seconds() << std::endl;

  std::cout << sstream.str();
}

Results:

2015-Oct-27
2015/10/27
2015-Oct-27 14:25:18.614684
14:25:18.614684
14/25/18/614684
2015-Oct-27
2015/10/27
2015-Oct-27 14:25:18.614684
14:25:18.614684
sfanjoy
  • 640
  • 6
  • 16