问题描述
我在找东西,我presumed会很简单 - 给定的本地Unix时间在一个特定的时间段(指定为字符串,如美国/纽约 - 注意,是的不是的我的本地时间),拿在格林尼治标准时间对应的时间价值。即沿东西线
I'm looking for something that I presumed would be very simple - given local Unix time in a specific time zone (specified as a string, e.g., "America/New_York" - note that's not my local time), get the corresponding time value in GMT. I.e., something along the lines of
time_t get_gmt_time(time_t local_time,
const char* time_zone);
作为看似简单,因为它听起来,最接近我能找到来自timegm的手册页以下code片断:
As deceptively simple as it sounds, the closest I could find was the following code snippet from timegm's man page:
#include <time.h>
#include <stdlib.h>
time_t
my_timegm(struct tm *tm)
{
time_t ret;
char *tz;
tz = getenv("TZ");
setenv("TZ", "", 1);
tzset();
ret = mktime(tm);
if (tz)
setenv("TZ", tz, 1);
else
unsetenv("TZ");
tzset();
return ret;
}
有一定有比这挑衅不是线程安全的憎恶一个更好的办法,对不对?右??
There gotta be a better way than this belligerently not thread-safe abomination, right? Right??
推荐答案
想在这里添加更多的细节。
Wanted to add a bit more detail here.
如果您尝试以下操作:
#include <stdio.h>
#include <time.h> /* defines 'extern long timezone' */
int main(int argc, char **argv)
{
time_t t, lt, gt;
struct tm tm;
t = time(NULL);
lt = mktime(localtime(&t));
gt = mktime(gmtime(&t));
printf( "(t = time(NULL)) == %x,\n"
"mktime(localtime(&t)) == %x,\n"
"mktime(gmtime(&t)) == %x\n"
"difftime(...) == %f\n"
"timezone == %d\n", t, lt, gt,
difftime(gt, lt), timezone);
return 0;
}
你会发现,时区转换确保:
you'll notice that timezone conversions make sure that:
-
mktime(本地时间(T))==牛逼
和 -
mktime(gmtime的(T))== T +时区
,结果
因此: -
difftime(mktime(gmtime的(T)),mktime(本地时间(T)))==时区
结果
(后者是任何初始化的全局变量tzset()
或任何时区转换函数的调用)。
mktime(localtime(t)) == t
, andmktime(gmtime(t)) == t + timezone
,
therefore:difftime(mktime(gmtime(t)), mktime(localtime(t))) == timezone
(the latter is a global variable initialized by eithertzset()
or the invocation of any timezone conversion function).
上面的示例输出:
$ TZ=GMT ./xx
(t = time(NULL)) == 4dd13bac,
mktime(localtime(&t)) == 4dd13bac,
mktime(gmtime(&t)) == 4dd13bac
difftime(...) == 0.000000
timezone == 0
$ TZ=EST ./xx
(t = time(NULL)) == 4dd13baf,
mktime(localtime(&t)) == 4dd13baf,
mktime(gmtime(&t)) == 4dd181ff
difftime(...) == 18000.000000
timezone == 18000
$ TZ=CET ./xx
(t = time(NULL)) == 4dd13bb2,
mktime(localtime(&t)) == 4dd13bb2,
mktime(gmtime(&t)) == 4dd12da2
difftime(...) == -3600.000000
timezone == -3600
在这个意义上说,你试图别倒着 - time_t的
被视为的绝对的参与联合国* X,即总相对于划时代(0:00 UTC在01/01/1970)。
In that sense, you're attempting to "do it backwards" - time_t
is treated as absolute in UN*X, i.e. always relative to the "EPOCH" (0:00 UTC on 01/01/1970).
UTC和当前时区(最后一个 tzset()
调用)之间的区别是总是在外长时区
全球
The difference between UTC and the current timezone (last tzset()
call) is always in the external long timezone
global.
这不摆脱环境操纵uglyness的,但你可以节省自己的通过 mktime去努力()
。
That doesn't get rid of the environment manipulation uglyness, but you can save yourself the effort of going through mktime()
.
这篇关于在Linux上的时区转换C API,任何人吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!