这是我的代码:
#include <time.h>
#include <stdio.h>
time_t my_timegm (struct tm *tm, char *tz_offset);
int
main (void)
{
struct tm time_tm;
time_t start_timet, end_timet;
time_tm.tm_sec = 0;
time_tm.tm_min = 0;
time_tm.tm_hour = 0;
time_tm.tm_mday = 1;
time_tm.tm_mon = 0;
time_tm.tm_year = 2023 - 1900;
time_tm.tm_isdst = -1;
start_timet = my_timegm (&time_tm, "Etc/GMT-6");
printf ("\n%li ", start_timet);
start_timet = my_timegm (&time_tm, "America/Chicago");
printf ("\n%li ", start_timet);
}
Run Code Online (Sandbox Code Playgroud)
my_timegm 是
#include <time.h>
#include <stdlib.h>
time_t
my_timegm (struct tm *tm, char *tz_offset)
{
time_t ret;
char *tz;
tz = getenv ("TZ");
setenv ("TZ", tz_offset, 1);
tzset ();
ret = mktime (tm);
if (tz)
setenv ("TZ", tz, 1);
else
unsetenv ("TZ");
tzset ();
return ret;
}
Run Code Online (Sandbox Code Playgroud)
输出是:
1672509600
1672552800
为什么会有 43200 秒(12 小时)的差异?或者,为什么 GMT-6 与 America/Chicago(UTC-6)不同?
归咎于 POSIX。
当环境变量的 POSIX 规范TZ
最初创建时,正时区数字被分配给西半球的时区,因为这可能是各个 Unix 系统开发人员现有实践中可以达成的唯一共识......他们中的大多数或全部当时的总部都在美国大陆,所以他们不想在自己的地盘上开始使用那个讨厌的减号。
本质上,TZ=xxx-6
将指定一个时区标记xxx
,您可以通过从本地时间减去 6 小时来获取 UTC。
出于遗留兼容性原因,该zoneinfo
数据库(曾经称为Olson 时区数据库,现在由 IANA 维护)对其时区使用相同的符号约定。Etc/GMTxx
$ TZ=GMT-6 date # legacy POSIX
Sun 11 Jun 10:23:18 GMT 2023 # note: GMT is a lie here!
$ TZ=Etc/GMT-6 date # modern zoneinfo form
Sun 11 Jun 10:23:25 +06 2023
$ TZ=GMT6 date # legacy POSIX
Sat 10 Jun 22:24:31 GMT 2023 # note: GMT is a lie here!
TZ=Etc/GMT+6 date # modern zoneinfo form
Sat 10 Jun 22:24:35 -06 2023
Run Code Online (Sandbox Code Playgroud)
请注意,当您使用该zoneinfo
表单时,与时间戳(+06
或-06
)一起显示的 UTC 偏移量与您可能期望的时区名称具有相反的符号zoneinfo
。