1

I am trying to convert date-times that i am receiving into a particular format to insert into a MySQL database. The program is written in C++, and the following solution works but I feel it is horribly inefficient.

The input is : Mon Nov 08 17:41:23 +0000 2010
The desired output format is: YYYY-MM-DD HH:MM:SS
So for this example the output would be: 2010-11-08 17:41:23

I have included the relevant parts of the code.

    //class variable
    std::map<std::string, std::string> monthMap;

void processor::initializeMonthMap(){
    monthMap["Jan"] = "01";
    monthMap["Feb"] = "02";
    monthMap["Mar"] = "03";
    monthMap["Apr"] = "04";
    monthMap["May"] = "05";
    monthMap["Jun"] = "06";
    monthMap["June"] = "06";
    monthMap["Jul"] = "07";
    monthMap["July"] = "07";
    monthMap["Aug"] = "08";
    monthMap["Sept"] = "09";
    monthMap["Sep"] = "09";
    monthMap["Oct"] = "10";
    monthMap["Nov"] = "11";
    monthMap["Dec"] = "12";
}

inline std::string processor::convertDate(std::string input) {
    //Format: Mon Nov 08 17:41:23 +0000 2010
    //To get to YYYY-MM-DD HH:MM:SS

    std::stringstream  newString(input);
    std::string temp1;
    std::string temp2;

    // Read Day in txt, discard
    newString >> temp1;

    //Read month, convert to number
    newString >> temp1;
    temp2 = "-" + monthMap[temp1] + "-";

    //Read Day in number
    newString >> temp1;
    temp2.append(temp1 + " ");

    //Read TimeStamp
    newString >> temp1;
    temp2.append(temp1);

    //Discard UTM adjustment
    newString >> temp1;

    //Read year
    newString >> temp1;

    //Add year to beginning of input
    temp1.append(temp2);

    return temp1;
}
Steven Dix
  • 124
  • 1
  • 9
  • You could use a regex (std::tr1 or boost::regex) for a clean solution. Also you could look into Boost.Date_Time if your format is standard. – anno Jan 20 '11 at 21:19
  • 2
    Have you measured a run of compiler optimized code? Your code looks pretty straightforward. You could squeeze out more, but is it worth it? Clean, understandable and reasonably efficient code like yours is worth a lot. (If you just renamed tempXXX to sensible names ... ;) – Peter G. Jan 20 '11 at 21:21
  • In general, I agree with @Peter. But in the case, using date/time libraries, this code can essentially be reduced to two lines: `get_date_from_string(..., format)` followed by `get_string_from_date(..., other_format)`. This would be clearer and more succinct. – Tim Jan 20 '11 at 21:30

3 Answers3

1

Use boost::date_time. You can format your input and output in a wide variety of ways with a format string.

Benjamin Lindley
  • 101,917
  • 9
  • 204
  • 274
1

You're parsing the string and fortunately you can build the output by simple appends. I don't see this getting more efficient.

However, it appears as if you can use seekg to position the cursor past day of the week and UTM adjustment.

http://www.cplusplus.com/reference/iostream/istream/seekg/

Lee Louviere
  • 5,162
  • 30
  • 54
  • The other methods mentioned may decrease code, but does not address efficiency IMO. – Lee Louviere Jan 20 '11 at 21:30
  • Thanks for the information. I do have a question about the stringstream. Do you think I would do better if I used string.find() instead of the building a stringstream everytime. – Steven Dix Jan 21 '11 at 00:22
  • 1
    If you know the lengths of the various parts are always the same (which they appear to be). If you want to ditch stringstream, I would use std::string::substr(start,count). – Lee Louviere Jan 21 '11 at 00:33
0

If you're on a POSIX system (i.e. not windows), you can use strptime: http://www.mkssoftware.com/docs/man3/strptime.3.asp

This takes a string and builds a struct tm, which you can output in any desired format via strftime.

There are some windows implementations of this, but it's not available by default. See more here: Convert a string to a date in C++

Community
  • 1
  • 1
Tim
  • 8,912
  • 3
  • 39
  • 57