Boost logo

Boost Users :

From: Filip Konvièka (filip.konvicka_at_[hidden])
Date: 2008-01-04 09:10:51


-----Original Message-----

From: Kahánek Petr
Sent: Friday, January 04, 2008 10:22 AM
To: 'boost-users_at_[hidden]'
Subject: Problems when constructing time_duration and ptime from string

Hi,

It seems there are problems with duration/ptime construction from string, no matter if one uses duration_from_string, time_from_string or operator >>.

Lets have the following code.
Using Windows XP service pack 2, MSVS2005 SP 1, Boost 1-34.1

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

using namespace std;
using namespace boost;
using namespace boost::posix_time;

int _tmain(int argc, _TCHAR* argv[])
{
  string str;
  time_duration td;
  ptime time;
  
  // try to construct duration and ptime from string where there's no blank space between date and time
  // 1) duration_from_string will pass
  // 2) "time_duration >>" will pass
  // 3) time_from_string will throw
  // 4) "ptime >>" will pass
  str = "2007-01-2010:00:05";
  td = duration_from_string(str);
  cout << "\"" << str << "\" == " << to_simple_string(td) << endl;
  stringstream ss(str);
  ss >> td;
  cout << "\"" << str << "\" == " << to_simple_string(td) << endl;
  
  try {
    time = time_from_string(str);
    cout << "\"" << str << "\" == " << time << endl;
  }
  catch(exception& e) {
    cout << "time_from_string could not construct time from \"" << str << "\", " << e.what() << endl;
  }
  try {
    stringstream ss(str);
    ss >> time;
    cout << "\"" << str << "\" == " << time << endl;
  }
  catch(exception& e) {
    cout << "operator >> could not get time from '" << "', " << e.what() << endl;
  }
  cout << endl << endl;

  // try to construct duration and ptime from "2007-01-20-1.xwerf" (mangled delimiters, rubbish in place of
  // fractional sec.) --> none will throw
  str = "2007-01-20-1.xwerf";
  td = duration_from_string(str);
  cout << "\"" << str << "\" == " << to_simple_string(td) << endl;

  stringstream ss2(str);
  ss2 >> td;
  cout << "\"" << str << "\" == " << to_simple_string(td) << endl;

  time = time_from_string(str);
  cout << "\"" << str << "\" == " << time << endl;

  stringstream ss3(str);
  ss3 >> time;
  cout << "\"" << str << "\" == " << time << endl;
  cout << endl << endl;

  // try to construct duration and ptime from "2007.01.20.1.xwerf" (mangled delimiters, rubbish in place of
  // fractional sec.) --> none will throw
  str = "2007.01.20.1.0xwerf";
  td = duration_from_string(str);
  cout << "\"" << str << "\" == " << to_simple_string(td) << endl;

  stringstream ss4(str);
  ss4 >> td;
  cout << "\"" << str << "\" == " << to_simple_string(td) << endl;

  time = time_from_string(str);
  cout << "\"" << str << "\" == " << time << endl;
  
  ss4 >> time;
  cout << "\"" << str << "\" == " << time << endl;
  cout << endl << endl;
  
  // try to construct duration and ptime from "2008-01-03"
  // none will throw, duration created although delimiter is "-", ptime created incorrectly
  str = "2008-01-03";
  td = duration_from_string(str);
  cout << "\"" << str << "\" == " << to_simple_string(td) << endl;

  stringstream ss5(str);
  ss5 >> td;
  cout << "\"" << str << "\" == " << to_simple_string(td) << endl;
 
  str = "2008-01-03";
  time = time_from_string(str);
  cout << "\"" << str << "\" == " << time << endl;

  stringstream ss6(str);
  ss6 >> time;
  cout << "\"" << str << "\" == " << time << endl;

  // even if duration is constructed, printing it to cout with operator << without conversion to string
  // will assert in strftime.c if hours are out of scope [0,23], or if minutes/seconds are out of [0,59]
  cout << str << " == " << td << endl; // CRASH

  return 0;
}

Output from this program:

"2007-01-2010:00:05" == 2007:34:30
"2007-01-2010:00:05" == 2007:34:30
time_from_string could not construct time from "2007-01-2010:00:05", bad lexical
 cast: source type value could not be interpreted as target "2007-01-2010:00:05" == not-a-date-time

"2007-01-20-1.xwerf" == 2007:01:20.100000
"2007-01-20-1.xwerf" == 2007:01:20.100000
"2007-01-20-1.xwerf" == 2007-Apr-13 15:01:20.100000 "2007-01-20-1.xwerf" == 2007-Apr-13 15:01:20.100000

"2007.01.20.1.0xwerf" == 2007:01:20.100000 "2007.01.20.1.0xwerf" == 2007:01:20.100000 "2007.01.20.1.0xwerf" == 2007-Apr-13 15:01:20.100000 "2007.01.20.1.0xwerf" == 2007-Apr-13 15:01:20.100000

"2008-01-03" == 2008:01:03
"2008-01-03" == 2008:01:03
"2008-01-03" == 2008-Mar-26 16:01:03
"2008-01-03" == 2008-Mar-26 16:01:03

..and then it will assert on cout << td. Durations that have hours out of [0,23] or min/sec out of [0,59] are parsed successfully but cannot be printed to cout using << (assert in strftime.c).

Workaround for "pure date", e.g. "2007-01-10", is to append "0" to it. "2007-01-10 0" is parsed OK.

I guess these can be considered bugs?

Br,
Petr


Boost-users list run by williamkempf at hotmail.com, kalb at libertysoft.com, bjorn.karlsson at readsoft.com, gregod at cs.rpi.edu, wekempf at cox.net