将 UTC 日期和时间转换为 UNIX 时间会给出错误的(时区不同)值。为什么?

标签 c utc epoch

我编写了一个小函数,将 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/

相关文章:

c - 主函数的参数,无法理解!

objective-c - 宏可以接受类型吗?

c - 关于为 arm 目标编译应用程序时使用的浮点 abi 标志

python - 如何在 python 和 django 中使用 Pytz 根据给定的 UTC 偏移量转换数据和时间?

java - 如何在java中检查LocalDateTime实例是本地还是UTC?

linux - bash 文件设置变量为纪元时间

使用套接字连接到许多服务器之一

python - 模块 pytz : UTC decrease instead of increase

ios - 获取当前时间转换为纪元时间

mysql - 为什么 Django 时区设置会影响纪元时间?