Reputation: 28868
My current computer gives the time with CET:
$ date
Mon Dec 1 21:31:41 CET 2014
However my locale is en_US:
$ locale | grep -i time
LC_TIME="en_US.UTF-8"
I would like to format an epoch string with C to my current local time zone, but I don't know how to tell strptime to change the default local:
#define _XOPEN_SOURCE
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
int
main(void)
{
struct tm tm;
char buf[255];
memset(&tm, 0, sizeof(struct tm));
strptime("1412200800", "%s", &tm);
strftime(buf, sizeof(buf), "%c %Z", &tm);
puts(buf);
exit(EXIT_SUCCESS);
}
The man page states that it formats the time according to the locale, but it seems to ignore my setting:
$ export LC_TIME=de_DE.UTF-8
$ locale | grep -i time
LC_TIME=de_DE.UTF-8
$ ./a.out
Thu Oct 2 00:00:00 2014 CEST
What I expect is:
Wed Thu Oct 1 22:00:00 2014 CET
OK, so I completely removed %s
and tried the following approach, but still no success:
#define _XOPEN_SOURCE
#include <string.h>
#include <time.h>
#include <stdio.h>
#include <stdlib.h>
#include <locale.h>
int
main(void)
{
struct tm *tim;
setlocale(LC_ALL, "");
char buf[255];
time_t c;
c = strtoul("1412200800", NULL, 0);
tim = localtime(&c);
strftime(buf, sizeof(buf), "%c" , tim);
puts(buf);
printf("%s %s\n", tzname[0], tzname[1]);
exit(EXIT_SUCCESS);
}
The output is still now what I'd expect:
gcc strptime_test.c && ./a.out
Thu 02 Oct 2014 12:00:00 AM CEST
CET CEST
Instead of using localtime(&c);
I now use:
tim = gmtime(&c);
strftime(buf, sizeof(buf), "%c" , tim);
Which give the desired behaviour:
Wed 01 Oct 2014 10:00:00 PM GMT
Upvotes: 1
Views: 1773
Reputation: 141628
Your code is using a non-standard glibc extension to strptime; %s
is the number of seconds since epoch.
According to Epoch Converter, 1412200800
is Wed, 01 Oct 2014 22:00:00 GMT
so your program is behaving correctly. However, it's unclear whether epoch seconds are to be taken in UTC, or in your local timezone, so as loreb notes in comments you may also need to call a time-zone conversion function.
You will have to make a decision as to whether times (i.e. contents of time_t
and struct tm
objects) in your program are times in UTC, or local times.
I would suggest the following fix: replace strptime
with
time_t c = 1412200800;
tm = *gmtime(&c);
The other function that might be used here instead of gmtime
is localtime
.
BTW I think you are mixing up locales and timezones: "locale" means the way that the time is formatted; for example the default might be:
Sun Oct 1 00:00:00 2014
but the locale-formatted version would be:
Sun, Oct 01, 2014 12:00:00 AM
Time-zones and locales are different things. (One locale may span multiple timezones, and one timezone may contain multiple locales).
NB. in C, the default locale is the C locale, not the system one. To read locale from environment variables, do:
#include <locale.h>
// in main()
setlocale(LC_ALL, "");
Upvotes: 1