5

I have a date time that comes from mysql. I need to extract each part:

int year;
int month;
int day;
int hour;
int min;
int sec;

example:

2014-06-10 20:05:57

Is there a simpler way than running it through stringstream for each component? (no boost or c++11 solutions please).

Thanks

jmasterx
  • 52,639
  • 96
  • 311
  • 557
  • 1
    Note that you almost certainly want to parse "yyyy-MM-dd HH:mm:ss". – Hot Licks Jun 11 '14 at 00:55
  • Dang your last sentence. I was like "`std::get_time`! `std::get_time`! `std::get_time`! Aww crap!" – chris Jun 11 '14 at 00:55
  • No, I'm asking how to do it in C++ given the std string date time – jmasterx Jun 11 '14 at 00:55
  • Well, not quite `std::get_time` is [`std::time_get`](http://en.cppreference.com/w/cpp/locale/time_get), available pre-C++11. – chris Jun 11 '14 at 00:57
  • If it works on c++98 it is an option, I've never head of fscanf – jmasterx Jun 11 '14 at 01:01
  • @Milo What would January 1, 2014 at 9:00am look like as it comes from your database? "2014-01-01 09:00:00"? If so, your fields are fixed width, which will facilitate plain old index-based string manipulations. – DavidO Jun 11 '14 at 01:01
  • Then `substr` could be useful, much as I hate to suggest implementing yet another quick-and-dirty date parser. ...but fixed width... why not? Year is at positions 0-3, month at 5-6, day at 8-9, hour at 11-12, minute at 14-15, and second at 17-18. – DavidO Jun 11 '14 at 01:03
  • Whatever you implement, just wrap it in a subroutine call so that it's easy to change the internal implementation if you later decide to do something more forgiving/robust. Implement the simple solution, set up a few unit / regression tests, and move on. – DavidO Jun 11 '14 at 01:06
  • I don't understand why `sscanf` is not option? – R Sahu Jun 11 '14 at 01:07

1 Answers1

7

sscanf() is probably the most straightforward option. It is a C library function, so purists might disapprove it.

Here is an example:

int year;
int month;
int day;
int hour;
int min;
int sec;

const char * str = "2014-06-10 20:05:57";

if (sscanf(str, "%d-%d-%d %d:%d:%d", &year, &month, &day, &hour, &min, &sec) == 6)
{
    // sscanf() returns the number of elements scanned, so 6 means the string had all 6 elements.
    // Else it was probably malformed.
}

And here is a live test.

Another nice solution would also be to use a C++11 regex which would make for a more robust parsing of the string.

glampert
  • 4,371
  • 2
  • 23
  • 49
  • @πάνταῥεῖ yeah but if the OP wanted to handle lots of formats i am sure he would consider c++11 or any of the boost functions that can help with this. – Fantastic Mr Fox Jun 11 '14 at 01:12
  • I guess the point is you can have robust, or you can have simple and dependency-free. This is a case where simple and dependency free has been requested. – DavidO Jun 11 '14 at 01:13
  • Agreed, for a flexible solution, he should go for a RegExp. – glampert Jun 11 '14 at 01:13
  • @glampert But then he would "have two problems." ;) – DavidO Jun 11 '14 at 01:20