[date_time] is it possible to parse a string out from given patterns?
Is it possible to parse a date out from a string like this? The example below is from a java program. private static final String PLANSTART_PATTERN = "dd.MM.yyyy HH:mm"; /** * Converts a String of type 01.01.2005 to a * CDate object * @param sForcamDate * @return the converted object */ private CDate convertToCDate(String sForcamDate, String sPattern) { if (sForcamDate == null || sForcamDate.length() == 0) return null; try { SimpleDateFormat sdf = new SimpleDateFormat(sPattern, Locale.getDefault()); sdf.parse(sForcamDate); Calendar cal = sdf.getCalendar(); return new CDate(cal.getTime()); } catch (ParseException ex) { return null; } } For more information on SimpleDateFormat see: http://java.sun.com/j2se/1.4.2/docs/api/java/text/SimpleDateFormat.html
On Wed, 26 Oct 2005 09:26:43 +0200, Roman Morokutti wrote
Is it possible to parse a date out from a string like this? The example below is from a java program.
private static final String PLANSTART_PATTERN = "dd.MM.yyyy HH:mm";
...snip code from another language which shouldn't be posted here ;-) Yes, trivially. I've shown 2 functions below. One that uses exceptions for error handling and one that just ignores errors. The exception based program prints the error and then returns not-a-date-time. parse_jdate2, on the other hand, just returns not-a-date-time on a parse failure. You'll need 1.33 for this code to work. Jeff -------------- Output from the program below is: 2005-Dec-01 10:30:00 Day of month value is out of range 1..31 not-a-date-time 2005-Dec-01 10:30:00 not-a-date-time #include "boost/date_time/posix_time/posix_time.hpp" #include <sstream> using namespace boost::gregorian; using namespace boost::posix_time; ptime parse_jdate1(const std::string& s) { ptime t; try { std::stringstream ss(s.c_str()); time_input_facet* timefacet = new time_input_facet("%d.%m.%Y %H:%M"); ss.imbue(std::locale(std::locale::classic(), timefacet)); ss.exceptions(std::ios_base::failbit); // turn on exceptions ss >> t; } catch(std::exception& e) { std::cout << e.what() << std::endl; } return t; } ptime parse_jdate2(const std::string& s) { ptime t; std::stringstream ss(s.c_str()); time_input_facet* timefacet = new time_input_facet("%d.%m.%Y %H:%M"); ss.imbue(std::locale(std::locale::classic(), timefacet)); ss >> t; return t; } int main() { std::cout << parse_jdate1("01.12.2005 10:30") << std::endl; std::cout << parse_jdate1("garbage_string") << std::endl; std::cout << parse_jdate2("01.12.2005 10:30") << std::endl; std::cout << parse_jdate2("garbage_string") << std::endl; return 0; }
Hi Jeff, Jeff Garland wrote:
...snip code from another language which shouldn't be posted here ;-) well, I should be aware of this.
I have the latest version of boost every day. I make a build every night on the whole boost project. Great job of you all. I had never have any- time problems with one build. It always went through. First with mingw now with vc-80. Your examples are the correct represantation of the example postet. One question left. First I thought the '%' sign is a placeholder for equal patterns. As I then tried to modify your examples using a pattern instead of time_input_facet* timefacet = new time_input_facet("%d.%m.%Y %H:%M"); this one: time_input_facet* timefacet = new time_input_facet("dd.mm.YYYY HH:MM"); the whole program crashed. Are there intentions to support patterns with the latter? Greetings Roman
On Wed, 26 Oct 2005 16:41:09 +0200, Roman Morokutti wrote
Hi Jeff,
Jeff Garland wrote:
...snip code from another language which shouldn't be posted here ;-) well, I should be aware of this.
I have the latest version of boost every day. I make a build every night on the whole boost project. Great job of you all. I had never have any- time problems with one build. It always went through. First with mingw now with vc-80.
Your examples are the correct represantation of the example postet. One question left.
First I thought the '%' sign is a placeholder for equal patterns. As I then tried to modify your examples using a pattern instead of
Well, no modification was needed. You should take a look at the docs -- in case you haven't found this: http://www.boost.org/doc/html/date_time/date_time_io.html#date_time.format_f...
time_input_facet* timefacet = new time_input_facet("%d.%m.%Y %H:%M");
this one:
time_input_facet* timefacet = new time_input_facet("dd.mm.YYYY HH:MM");
the whole program crashed. Are there intentions to support patterns with the latter?
No, I have no plan to support other string definition forms. I think the current flags give you all the same capabilities and is more consistent with C++ standards. That said, I am concerned that the program crashed -- that doesn't sound like desireable behavior. I suspect the reason has something to do with the fact that the string you are passing doesn't have any valid strings to parse -- something I'm pretty sure we don't test. Anyway, I'll put that on the todo list to add a test and better specify the behavior related to completely invalid format strings. It probably would be nice to have an exception in this case... Jeff Jeff
Jeff Garland wrote: <snip>
That said, I am concerned that the program crashed -- that doesn't sound like desireable behavior. I suspect the reason has something to do with the fact that the string you are passing doesn't have any valid strings to parse -- something I'm pretty sure we don't test. Anyway, I'll put that on the todo list to add a test and better specify the behavior related to completely invalid format strings. It probably would be nice to have an exception in this case...
Jeff
Jeff (yes, I heard you already :-)
This seems like a job for assert to me, unless you expect user-input to be used in the format string somehow? -- don't quote this
Thanks Jeff, for the examples and explanations. Greetings Roman
Jeff Garland wrote:
On Wed, 26 Oct 2005 09:26:43 +0200, Roman Morokutti wrote
Is it possible to parse a date out from a string like this? The example below is from a java program.
private static final String PLANSTART_PATTERN = "dd.MM.yyyy HH:mm";
Yes, trivially.
IMHO, not trivial enough for such a trivial (and common) task.
ptime parse_jdate1(const std::string& s) {
ptime t; try { std::stringstream ss(s.c_str()); time_input_facet* timefacet = new time_input_facet("%d.%m.%Y %H:%M"); ss.imbue(std::locale(std::locale::classic(), timefacet)); ss.exceptions(std::ios_base::failbit); // turn on exceptions ss >> t; } catch(std::exception& e) { std::cout << e.what() << std::endl; } return t;
}
I think the best way would be to support something like ptime t; my_istream >> time_format("%d.%m.%Y %H:%M") >> t; time_format would be defined as something similar to implemetation_defined time_format(const char *format, const std::locale &loc = std::locale::classic()); and using io manipulators it will do all the magic (facet/imbue/whatever) stuff automatically. This will be much easier to use... Just a thought, Yuval
participants (4)
-
Jeff Garland
-
Roman Morokutti
-
Simon Buchan
-
Yuval Ronen