我编写了一个小函数,将 UTC 中的日期和时间转换为 UNIX 时间(纪元时间)。但是,我获得的值取决于我所在的时区。
这是代码
#include<stdio.h>
#include<time.h>
time_t GenerateUnixTimeStampFromDateAndTime(char *DateAndTime);
void main()
{
long int UnixTime=0;
char *CurrentTime="01/22/2019 06:30:00";
UnixTime = (long int)GenerateUnixTimeStampFromDateAndTime(CurrentTime);
printf("Current Unix Time= %ld\r\n", UnixTime);
}
time_t GenerateUnixTimeStampFromDateAndTime(char *DateAndTime)
{
struct tm ti={0};
if( sscanf(DateAndTime, "%d/%d/%d %d:%d:%d", &ti.tm_mon, &ti.tm_mday, &ti.tm_year, &ti.tm_hour, &ti.tm_min, &ti.tm_sec) != 6 )
return -1;
ti.tm_year = ti.tm_year - 1900;
ti.tm_mon = ti.tm_mon - 1;
return mktime(&ti);
}
我得到的答案是1548118800,即01/22/2019 01:00:00,即-5:30,这是我所在的时区(印度)。如果我将我的电脑时区更改为 UTC,那么它会给出正确的值 1548138600。
我需要进行哪些更改才能使其与时区无关?
最佳答案
根据记录,mktime()
获取本地时间中的分解时间分量。
首先,保存用户当前时区:
char *old_timezone, *temp;
temp = getenv("TZ");
if (temp) {
const size_t len = temp;
old_timezone = malloc(len + 1);
if (!old_timezone) {
fprintf(stderr, "Out of memory!\n");
exit(EXIT_FAILURE);
}
if (len > 0)
memcpy(old_timezone, temp, len);
old_timezone[len] = '\0';
} else
old_timezone = NULL;
如果用户使用系统默认值,old_timezone
将为NULL。
接下来,将当前时区(对于此过程)设置为 UTC:
setenv("TZ", "UTC", 1);
tzset();
请注意,如果需要,您可以使用任何时区说明符来代替上面的 "UTC"
;请参阅tzset()
了解详情。 tzset()
调用通常由 C 库在内部完成,但在这里显式地执行它可以帮助我们人类看到刚刚发生的特定于时区的事情。
此时,mktime()
将以 UTC 进行操作,localtime()
和 gmtime()
将返回相同的结果。
然后,恢复时区
if (old_timezone) {
setenv("TZ", old_timezone, 1);
free(old_timezone);
old_timezone = NULL;
} else
unsetenv("TZ");
tzset();
请注意,除了当前进程(以及您可能通过 popen()
或 system()
或 fork( 创建的任何子进程)之外,这不会影响任何内容)
和 exec()
)。时区与区域设置一样,是每个进程的属性。
正在运行
unsetenv("TZ");
tzset();
会将此进程的当前时区更改为系统默认时区。
<小时/>如果您的程序明确以 UTC 运行,您可以这样做
/* This program works explicitly in the UTC timezone.
User/system timezone configuration is completely ignored. */
setenv("TZ", "UTC", 1");
tzset();
靠近 main()
的开头。
关于将 UTC 日期和时间转换为 UNIX 时间会给出错误的(时区不同)值。为什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54305986/