在 C/C++ 中在当地时间和 GMT/UTC 之间转换
Posted
技术标签:
【中文标题】在 C/C++ 中在当地时间和 GMT/UTC 之间转换【英文标题】:Converting Between Local Times and GMT/UTC in C/C++ 【发布时间】:2010-10-20 04:39:02 【问题描述】:在 C/C++ 中在本地时间和 UTC 之间转换日期时间的最佳方法是什么?
“日期时间”是指包含日期和时间的一些时间表示。我会很高兴time_t
、struct tm
或任何其他使之成为可能的表示。
我的平台是 Linux。
这是我要解决的具体问题:我得到一对包含儒略日期和一天中的秒数的值。这些值在格林威治标准时间。我需要将其转换为本地时区“YYYYMMDDHHMMSS”值。我知道如何将儒略日期转换为 Y-M-D,显然很容易将秒转换为 HHMMSS。然而,棘手的部分是时区转换。我确信我可以找到解决方案,但我更愿意找到一种“标准”或“众所周知”的方式,而不是四处走动。
一个可能相关的问题是Get Daylight Saving Transition Dates For Time Zones in C
【问题讨论】:
【参考方案1】:您应该使用gmtime
/localtime
和timegm
/mktime
的组合。这应该为您提供在struct tm
和time_t
之间进行转换的正交工具。
对于 UTC/GMT:
time_t t;
struct tm tm;
struct tm * tmp;
...
t = timegm(&tm);
...
tmp = gmtime(t);
当地时间:
t = mktime(&tm);
...
tmp = localtime(t);
所有tzset()
所做的都是从TZ
环境变量设置内部时区变量。我认为这不应该被多次调用。
如果您尝试在时区之间进行转换,您应该修改struct tm
的tm_gmtoff
。
【讨论】:
谢谢!我知道必须存在类似 timegm() 的东西,但不知道名称。 很高兴为您提供帮助。时间转换可能是一个相当棘手的领域。尽可能将所有内容存储在 UTC 中通常是个好主意。时区之间的转换更加棘手! 是的,不幸的是,系统的设计者选择了本地时间作为消息传递协议的“标准”时间戳格式。当人们这样做时,我讨厌它。 Windows 中没有timegm。 我可能会将此作为一个单独的问题提出(挖掘现在提到tm_gmtoff
的问题,并且列表很短),但是:您能否举一个修改 tm_gmtoff 并具有那做点什么有用的?当我这样做时,它似乎并没有改变例如strftime(buf, BUFSIZ, "%FT%T%z (%+ %z)", tm);
的输出。 ??【参考方案2】:
如果在 Windows 上,您没有可用的 timegm():
struct tm *tptr;
time_t secs, local_secs, gmt_secs;
time( &secs ); // Current time in GMT
// Remember that localtime/gmtime overwrite same location
tptr = localtime( &secs );
local_secs = mktime( tptr );
tptr = gmtime( &secs );
gmt_secs = mktime( tptr );
long diff_secs = long(local_secs - gmt_secs);
或类似的东西......
【讨论】:
不应该secs
和gmt_secs
相同吗?我认为您可以简化一下。
我试过这个。我试图通过逆向测试结果来验证它。在某些时候它可以工作,而对于其他人来说,它会关闭一个小时。我猜这是因为 DST 在我尝试的不同位置的不同日期开始和停止(使用 GMT,但转换为 PST 本地时间)。有什么办法可以弥补吗?
此版本使用 Boost POSIX 时间库,尽管不同时区的 DST 日期不同,但似乎可以正常工作:***.com/a/6849810/857029。【参考方案3】:
如果您需要担心使用时区规则转换日期/时间,您可能需要查看ICU。
【讨论】:
以上是关于在 C/C++ 中在当地时间和 GMT/UTC 之间转换的主要内容,如果未能解决你的问题,请参考以下文章