Sideshow Bob
Sideshow Bob

Reputation: 4716

Parsing a time string in portable c++

Can anyone suggest a nicer way of writing the following piece of code?

I'd like to avoid using boost::time as that raises linking issues, and can't use strptime() because I'm on msvc.

#include <ctime>

int strtomonth(string s)
{
    const char *months[12] = {"Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec"};
    for (int i=0;i<12;i++)
        if (strcmp(months[i],s.c_str())==0)
            return i;
    return -1;
}

time_t get_compilation_time()
{
    stringstream s;
    s << __TIMESTAMP__; // formatted like "Tue Dec  6 13:42:54 2011"
    string weekday,month;
    int day,h,m,sec,year;
    char colon;
    s >> weekday >> month >> day >> h >> colon >> m >> colon >> sec >> year;

    tm compile_time;
    compile_time.tm_sec = 0;
    compile_time.tm_min = 0;
    compile_time.tm_hour = 0;
    compile_time.tm_mday = day;
    compile_time.tm_mon = strtomonth(month);
    compile_time.tm_year = year-1900;
    compile_time.tm_isdst = 0;
    compile_time.tm_wday = 0;
    compile_time.tm_yday = 0;

    time_t cmptime = mktime(&compile_time);
    return cmptime;
}

(I appreciate in this case I could make a pre-build step in python or similar to create a "buildtime.h" and save me the runtime computation, but as this now works and overheads aren't an issue I'll stick with it).

But... C-style struct initialization with undefined behaviour if I get it wrong, references in what should be a purely functional piece of code, declaring variables which get discarded, parsing month strings myself ... yuck! Is there a better way?

Upvotes: 2

Views: 1489

Answers (2)

fjardon
fjardon

Reputation: 7996

You may want to take a look at the 'time_get' facet which is in the standard C++ library. http://www.cplusplus.com/reference/std/locale/time_get/

It provides some functions to parse date and time. You can see minimal examples at:

http://www.cplusplus.com/reference/std/locale/time_get/get_monthname/

http://www.cplusplus.com/reference/std/locale/time_get/get_weekday/

This is a pretty barebone implementation and may not suit all your needs.

Upvotes: 2

Constantinius
Constantinius

Reputation: 35069

But... C-style struct initialization with undefined behaviour if I get it wrong, references in what should be a purely functional piece of code, declaring variables which get discarded, parsing month strings myself ... yuck! Is there a better way?

Yes! Use an external library. (like boost::time)

I'd like to avoid using boost::time as that raises linking issues

There's tons of documentation to get boost to run/compile, it is really not that hard.

You have always the tradeoff between linking to existing libraries or writing it your own. You have to choose which option has the lower overhead/higher gain.

Upvotes: 4

Related Questions