What else shall I do before reuse a stringstream for date parsing?

To accelerate date parsing, I have writen a class to encapsulate the date parsing logic as following. But the second call to CDateParser::parseDate(str) always failed to parse the date string. What else shall I do before reuse the stringstream object? #include <stdio.h> #include <iostream> #include <sstream> using namespace std; #include "boost/date_time/posix_time/posix_time.hpp" using namespace boost::gregorian; using namespace boost::posix_time; class CDateParser { public: static void initialize(); static time_t parseDate(const string& s); private: static stringstream m_ss; //!< stringstream object used internally for date parsing }; stringstream CDateParser::m_ss; time_t CDateParser::parseDate(const string& str) { ptime p; m_ss.clear(); m_ss << str; m_ss >> p; if (m_ss.fail()) { cout << "do not understand: " << str << endl; return 0; } tm t = to_tm(p); return mktime(&t); } void CDateParser::initialize() { time_input_facet* timefacet = new time_input_facet("%a, %d %b %Y %H:%M:%S %z"); // will be automatically deleted by related locale object m_ss.imbue(locale(locale::empty(), timefacet)); } int main() { CDateParser::initialize(); string str; time_t t; str = "Fri, 18 Jul 2008 11:53:14 GMT"; t = CDateParser::parseDate(str); cout << ctime(&t) << endl; str = "Sat, 19 Jul 2008 11:53:14 GMT"; t = CDateParser::parseDate(str); cout << ctime(&t) << endl; }

Bill David wrote:
To accelerate date parsing, I have writen a class to encapsulate the date parsing logic as following. But the second call to CDateParser::parseDate(str) always failed to parse the date string. What else shall I do before reuse the stringstream object?
#include <stdio.h>
#include <iostream> #include <sstream> using namespace std;
#include "boost/date_time/posix_time/posix_time.hpp" using namespace boost::gregorian; using namespace boost::posix_time;
class CDateParser { public: static void initialize(); static time_t parseDate(const string& s); private: static stringstream m_ss; //!< stringstream object used internally for date parsing };
stringstream CDateParser::m_ss;
time_t CDateParser::parseDate(const string& str) { ptime p; m_ss.clear(); m_ss << str; m_ss >> p; if (m_ss.fail()) { cout << "do not understand: " << str << endl; return 0; }
tm t = to_tm(p); return mktime(&t); }
void CDateParser::initialize() { time_input_facet* timefacet = new time_input_facet("%a, %d %b %Y %H:%M:%S %z"); // will be automatically deleted by related locale object m_ss.imbue(locale(locale::empty(), timefacet)); }
int main() { CDateParser::initialize();
string str; time_t t;
str = "Fri, 18 Jul 2008 11:53:14 GMT"; t = CDateParser::parseDate(str); cout << ctime(&t) << endl;
str = "Sat, 19 Jul 2008 11:53:14 GMT"; t = CDateParser::parseDate(str); cout << ctime(&t) << endl; }
You should invoke m_ss.seekg(ios_base::beg) before each parsing. Also, be careful with to_tm(). It is buggy. See https://svn.boost.org/trac/boost/ticket/1859 BR, Dmitry

2009/2/16 Dmitry Goncharov <dgoncharov@unison.com>
Bill David wrote:
To accelerate date parsing, I have writen a class to encapsulate the date parsing logic as following. But the second call to CDateParser::parseDate(str) always failed to parse the date string. What else shall I do before reuse the stringstream object?
#include <stdio.h>
#include <iostream> #include <sstream> using namespace std;
#include "boost/date_time/posix_time/posix_time.hpp" using namespace boost::gregorian; using namespace boost::posix_time;
class CDateParser { public: static void initialize(); static time_t parseDate(const string& s); private: static stringstream m_ss; //!< stringstream object used internally for date parsing };
stringstream CDateParser::m_ss;
time_t CDateParser::parseDate(const string& str) { ptime p; m_ss.clear(); m_ss << str; m_ss >> p; if (m_ss.fail()) { cout << "do not understand: " << str << endl; return 0; }
tm t = to_tm(p); return mktime(&t); }
void CDateParser::initialize() { time_input_facet* timefacet = new time_input_facet("%a, %d %b %Y %H:%M:%S %z"); // will be automatically deleted by related locale object m_ss.imbue(locale(locale::empty(), timefacet)); }
int main() { CDateParser::initialize();
string str; time_t t;
str = "Fri, 18 Jul 2008 11:53:14 GMT"; t = CDateParser::parseDate(str); cout << ctime(&t) << endl;
str = "Sat, 19 Jul 2008 11:53:14 GMT"; t = CDateParser::parseDate(str); cout << ctime(&t) << endl; }
You should invoke m_ss.seekg(ios_base::beg) before each parsing. Also, be careful with to_tm(). It is buggy. See https://svn.boost.org/trac/boost/ticket/1859
But after I do that, both invocations report "do not understand". And why clear can't rewind it?
BR, Dmitry _______________________________________________ Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost

Bill David wrote:
2009/2/16 Dmitry Goncharov <dgoncharov@unison.com>
Bill David wrote:
To accelerate date parsing, I have writen a class to encapsulate the date parsing logic as following. But the second call to CDateParser::parseDate(str) always failed to parse the date string. What else shall I do before reuse the stringstream object?
#include <stdio.h>
#include <iostream> #include <sstream> using namespace std;
#include "boost/date_time/posix_time/posix_time.hpp" using namespace boost::gregorian; using namespace boost::posix_time;
class CDateParser { public: static void initialize(); static time_t parseDate(const string& s); private: static stringstream m_ss; //!< stringstream object used internally for date parsing };
stringstream CDateParser::m_ss;
time_t CDateParser::parseDate(const string& str) { ptime p; m_ss.clear(); m_ss << str; m_ss >> p; if (m_ss.fail()) { cout << "do not understand: " << str << endl; return 0; }
tm t = to_tm(p); return mktime(&t); }
void CDateParser::initialize() { time_input_facet* timefacet = new time_input_facet("%a, %d %b %Y %H:%M:%S %z"); // will be automatically deleted by related locale object m_ss.imbue(locale(locale::empty(), timefacet)); }
int main() { CDateParser::initialize();
string str; time_t t;
str = "Fri, 18 Jul 2008 11:53:14 GMT"; t = CDateParser::parseDate(str); cout << ctime(&t) << endl;
str = "Sat, 19 Jul 2008 11:53:14 GMT"; t = CDateParser::parseDate(str); cout << ctime(&t) << endl; }
You should invoke m_ss.seekg(ios_base::beg) before each parsing. Also, be careful with to_tm(). It is buggy. See https://svn.boost.org/trac/boost/ticket/1859
But after I do that, both invocations report "do not understand". And why clear can't rewind it?
It works for me. I also replaced locale:empty() (non-existent on my system) with locale() in order to compile your example. BR, Dmitry

2009/2/16 Dmitry Goncharov <dgoncharov@unison.com>
Bill David wrote:
2009/2/16 Dmitry Goncharov <dgoncharov@unison.com>
Bill David wrote:
To accelerate date parsing, I have writen a class to encapsulate the date parsing logic as following. But the second call to CDateParser::parseDate(str) always failed to parse the date string. What else shall I do before reuse the stringstream object?
#include <stdio.h>
#include <iostream> #include <sstream> using namespace std;
#include "boost/date_time/posix_time/posix_time.hpp" using namespace boost::gregorian; using namespace boost::posix_time;
class CDateParser { public: static void initialize(); static time_t parseDate(const string& s); private: static stringstream m_ss; //!< stringstream object used internally for date parsing };
stringstream CDateParser::m_ss;
time_t CDateParser::parseDate(const string& str) { ptime p; m_ss.clear(); m_ss << str; m_ss >> p; if (m_ss.fail()) { cout << "do not understand: " << str << endl; return 0; }
tm t = to_tm(p); return mktime(&t); }
void CDateParser::initialize() { time_input_facet* timefacet = new time_input_facet("%a, %d %b %Y %H:%M:%S %z"); // will be automatically deleted by related locale object m_ss.imbue(locale(locale::empty(), timefacet)); }
int main() { CDateParser::initialize();
string str; time_t t;
str = "Fri, 18 Jul 2008 11:53:14 GMT"; t = CDateParser::parseDate(str); cout << ctime(&t) << endl;
str = "Sat, 19 Jul 2008 11:53:14 GMT"; t = CDateParser::parseDate(str); cout << ctime(&t) << endl; }
You should invoke m_ss.seekg(ios_base::beg) before each parsing. Also, be careful with to_tm(). It is buggy. See https://svn.boost.org/trac/boost/ticket/1859
But after I do that, both invocations report "do not understand". And why clear can't rewind it?
It works for me. I also replaced locale:empty() (non-existent on my system) with locale() in order to compile your example.
It seems you are using Linux while I am using Windows + VS2005. But I have just tried on Linux. It is runnable, but the result is wrong. The result should be: Fri, 18 Jul 2008 11:53:14 GMT Sat, 19 Jul 2008 11:53:14 GMT
BR, Dmitry
_______________________________________________ Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost

Bill David wrote:
2009/2/16 Dmitry Goncharov <dgoncharov@unison.com>
You should invoke m_ss.seekg(ios_base::beg) before each parsing. Also, be careful with to_tm(). It is buggy. See https://svn.boost.org/trac/boost/ticket/1859
But after I do that, both invocations report "do not understand". And why clear can't rewind it?
The function clear doesn't "rewind" the stream, it just clears the flags, like eof. The old stream content is still there. Bo Persson

It seems I should call both clear and str to get the right result. 2009/2/17 Bo Persson <bop@gmb.dk>
Bill David wrote:
2009/2/16 Dmitry Goncharov <dgoncharov@unison.com>
You should invoke m_ss.seekg(ios_base::beg) before each parsing. Also, be careful with to_tm(). It is buggy. See https://svn.boost.org/trac/boost/ticket/1859
But after I do that, both invocations report "do not understand". And why clear can't rewind it?
The function clear doesn't "rewind" the stream, it just clears the flags, like eof. The old stream content is still there.
Thanks, I have tried. If I don't call clear, the fail status will impact the later call to this logic.
Bo Persson
_______________________________________________ Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
participants (3)
-
Bill David
-
Bo Persson
-
Dmitry Goncharov