繁体   English   中英

为什么我使用 tm 时间得到不正确的时间?

[英]Why am I getting incorrect time using tm time?

我提前一分钟减去当前时间,但是 C++ 说差异是 18000 秒,相当于 300 分钟(4 小时)。 真的很困惑为什么会这样。 这是我的代码:

#include <stdio.h>
#include <time.h>
#include <iostream> 

int main(){
    time_t timer; 
    struct tm t = {0}; 
    double seconds; 
    
    t.tm_year = 122; //2022
    t.tm_mon = 7 //august
    t.tm_mday = 29; //29
    t.tm_hour = 21; //10pm
    t.tm_min = 35; //35
    t.tm_sec = 0; 

    time(&timer); //get current time
    seconds = difftime(timer, mktime(&t)); 

    std::cout << seconds; 
}

C 库中的time function 处理 UTC 时间,而mktime假定您的本地时间。 这在文档中是明确的。

time() 以自 Epoch 1970-01-01 00:00:00 +0000 ( UTC ) 以来的秒数返回时间。

mktime() function 将分解的时间结构(表示为 local time )转换为日历时间表示。

考虑这段代码:

#include <stdio.h>
#include <time.h>
#include <string.h>
#include <iostream> 

int main(){
    struct tm t; 
    memset(&t,0,sizeof(tm));
    t.tm_year = 2022 - 1900;
    t.tm_mon = 8 - 1;  
    t.tm_mday = 29; 
    t.tm_hour = 23;
    t.tm_min = 28; 
    t.tm_sec = 0;
    t.tm_isdst = 1;
    
    time_t mktm = mktime(&t);
    time_t timer = time(0);

    double seconds = difftime(timer,mktm); 
    std::cout << seconds << std::endl;
    std::cout << mktm << std::endl;
    std::cout << timer << std::endl;

    struct tm local;
    localtime_r( &mktm, &local );
    std::cout << "gmtoff:" << local.tm_gmtoff << std::endl;
}

观察我通过了t.tm_isdst=1因为我在芝加哥,目前正处于白天,我得到了这个:

$ g++ /tmp/test2.cpp -o ./test2
$ ./test2
30
1661833680
1661833710
gmtoff:-18000

因此,这告诉我时间结构仅比当前时间早 30 秒,这是您的预期结果。 我还要求打印负 18,000 秒(-5 小时)的本地时间 gmt 偏移量,这似乎是正确的。

请注意,时间戳16618336801661833710都是 GMT 时间,您可以查看 epochconverter.com

在此处输入图像描述

现在,当我在Godbolt Compiler Explorer上运行这个确切的代码时,我得到了不同的结果:

18031
1661816160
1661834191
gmtoff:0

所以它现在告诉我,现在的差异是 5 小时。 这是因为它假设我经过的时间是伦敦时间:但现在伦敦时间是凌晨 4.41。

请注意,gmtoffset 现在为零,表示这台机器在伦敦(或将其时区设置为英国)。

因此,我认为在您的情况下正在发生的事情是您在 UTC-4(纽约?)的某个地方并登录了英国的计算机或使用编译器资源管理器作为我自己。

我有 windows 使用 bash.exe

$ /cygdrive/c/Windows/System32/tzutil.exe /s "Central America Standard Time"
$ date "+%a %d-%b-%Y %I:%M:%S %Z"
Tue 30-Aug-2022 01:10:01 CDT
$ /cygdrive/c/Windows/System32/tzutil.exe /g
Central America Standard Time
$ /cygdrive/c/Windows/System32/tzutil.exe /s "E. South America Standard Time"
$ date "+%a %d-%b-%Y %I:%M:%S %Z"
Tue 30-Aug-2022 01:10:48 CDT
$ ./a.out
Seconds: 6191
mktm   : 1661833680
timer  : 1661839871
gmtoff : -18000
$ tzutil /s "India Standard Time"
$ ./a.out
Seconds: 47632
mktm   : 1661792280
timer  : 1661839912
gmtoff : 19800

因此,a.out 的 output 会根据系统时序而变化,例如使用 TZ 环境变量(在面向 Linux 的操作系统)具有相同时序的来自两个星系的两个行星的方式。 我再次使用管理员权限将我的系统设置回 IST。

C:> C:\Windows\System32\tzutil.exe /g
India Standard Time

当 web 服务器/系统上的任何应用程序使用不同的 TZ/tzutil 位置更改时,同样适用于系统/移动/外部应用程序(如 ATM/...)内部的浏览器。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM