我当前的电脑给出了CET的时间:
$ date
Mon Dec 1 21:31:41 CET 2014
但我的语言环境是en_US:
$ locale | grep -i time
LC_TIME="en_US.UTF-8"
我想将带有C的纪元字符串格式化为我当前的本地时区,但我不知道如何告诉strptime更改默认的本地时间:
#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);
}
手册页指出它根据区域设置格式化时间,但似乎忽略了我的设置:
$ 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
我的期望是:
Wed Thu Oct 1 22:00:00 2014 CET
好的,所以我完全删除了%s
并尝试了以下方法,但仍然没有成功:
#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);
}
输出现在仍然是我所期望的:
gcc strptime_test.c && ./a.out
Thu 02 Oct 2014 12:00:00 AM CEST
CET CEST
而不是使用localtime(&c);
我现在使用:
tim = gmtime(&c);
strftime(buf, sizeof(buf), "%c" , tim);
这给出了所需的行为:
Wed 01 Oct 2014 10:00:00 PM GMT
答案 0 :(得分:1)
您的代码使用strptime的非标准glibc扩展名; %s
是纪元以来的秒数。
根据Epoch Converter,1412200800
为Wed, 01 Oct 2014 22:00:00 GMT
,因此您的程序行为正常。但是,目前还不清楚时间秒是以UTC还是在当地时区拍摄,因此评论中的loreb音符可能还需要调用时区转换功能。
您必须决定程序中的时间(即time_t
和struct tm
对象的内容)是UTC时间还是当地时间。
我建议采取以下解决方法:将strptime
替换为
time_t c = 1412200800;
tm = *gmtime(&c);
此处可能使用的另一个功能是gmtime
,而不是localtime
。
BTW我认为你正在混淆语言环境和时区:“语言环境”意味着格式化时间的方式;例如,默认值可能是:
Sun Oct 1 00:00:00 2014
但是语言环境格式的版本是:
Sun, Oct 01, 2014 12:00:00 AM
时区和区域设置是不同的东西。 (一个区域设置可能跨越多个时区,一个时区可能包含多个区域设置)。
NB。在C中,默认语言环境是C语言环境,而不是系统语言环境。要从环境变量中读取区域设置,请执行以下操作:
#include <locale.h>
// in main()
setlocale(LC_ALL, "");