views:

175

answers:

3

While doing the data/time parsing in c++ (converting a string in any format to a date), i found the following useful methods

1) strptime() - here the %d, %m etc can have either 1 or 2 characters. The function will take care of that. As a result of this it will enforce that we use a separator between two conversion specifiers. Ex: Its not valid to give %d%m it has be to %d/%m or any other separator. Also this does not support timezones.

2) Boost date IO - here the %d, %m has to have 2 characters. Now, the input string i get is not guaranteed to have this. As a result, its not possible to use this successfully. However, this does seem to support timezone, but not sure. because it says for inputs it does support timezone

So i am planning to use both in conjunction to determine the date. But i would like to get one where i can take into account the timezone as well. But none seems to be supporting that.

Does anybody have a suggestion? Rgds, AJ

A: 

Depends on the libc version, I'd say, and of course what you mean by `taking into account': Is it supposed to read the additional info and then ignore it, is it supposed to store the parsed info in the tm struct, or is it meant to convert to system/environment time?

glibc 2.10.1's strptime() does time zones, from the info page

`%z'
      The offset from GMT in ISO 8601/RFC822 format.

`%Z'
      The timezone name.

      _Note:_ Currently, this is not fully implemented.  The format
      is recognized, input is consumed but no field in TM is set.
hroptatyr
Is it possible for me to convert the following dates into GMT and have those values in tm?Tue, 19 Feb 2008 20:47:53 +0530 Tue, 28 Apr 2009 18:22:39 -0700 (PDT)If yes, it will be really helpful if you can provide me the code for that in unix (just a two or three liner)
AJ
A: 

As you noticed strptime doesn't directly support timezones. All it does is read formatted timezone-less data into a tm structure. You'll have to parse an optional timezone indicator yourself (unless it's fixed), and then set TZ and use mktime to convert into a time_t. If you set tm.is_dst to -1 you can even ask that mktime try to figure out the DST for you automatically.

Alternately you could construct your own parser using steams (boost supports a few formats, but may not be general enough). Again like above you can use mktime to compose a time_t.

Mark B
+1  A: 

@AJ: Added another answer so the code gets formatted

#include <stdio.h>
#include <sys/time.h>
#include <time.h>

int
main(void)
{
        struct tm tm[1] = {{0}};

        strptime("Tue, 19 Feb 2008 20:47:53 +0530", "%a, %d %b %Y %H:%M:%S %z", tm);
        fprintf(stdout, "off %ld\n", tm->tm_gmtoff);
        return 0;
}

And a run looks like (glibc 2.10.1):

freundt@clyde:pts/28:~/temp> ./test
off 19800
hroptatyr
Thanks a ton!Just curious, is this possible with glibc 2.9.x?! Do you know if it does or not?will try it anyhow, but have no access to linux machine at the moment.
AJ
Works on 2.9 as well.
hroptatyr
does this parse when Timezones are in 3 Letter formats like CST CDT etc?
AJ
glibc 2.10.1 does not support named timezones. That's what the info page means by "_Note:_ Currently, this is not fully implemented."
hroptatyr
Besides, the format specifier for time zone names would be %Z, so the snippet above is limited to numeric offsets.
hroptatyr