所以,这并不保证能够正常工作。我想知道有没有更妥善的方法?
嗯...我不完全明白你上面的结论是什么。time_t是一个unix特定类型,已经发展为POSIX标准。如果你收到它作为一个字符串,那么你必须处理它可能是一个64位数字的可能性(例如:FreeBSD使用64位的time_t)。
关于纪元时间,它并不总是那个纪元时间(unix的早期版本使用1972年1月1日,但我想我们中没有人见过这样的系统——我在家里运行着一个pdp-11的unix v7,并且它有32位的时间——那时候没有time_t类型,它是一个long int类型——并且它是基于实际的纪元时间)。
你必须小心,因为自从它的创造以来,unix时间一直是一个带符号的值,因此它从1970年1月1日开始,但你可以指定日期在那之前,只需使用负值即可,如下所示:
$ LANG=C date -u -r -2147483648
Fri Dec 13 20:45:52 UTC 1901
$ _
这就是为什么它会耗尽
$ LANG=C date -u -r 2147483647
Tue Jan 19 03:14:07 UTC 2038
$ _
在另一方面,你的问题不明确,因为你没有说明最终字符串数据要转换成哪个地区和时区(或格式)。最好使用标准的Unix时间函数(查找
gmtime(3)
,
localtime(3)
和与之关联的
struct tm
类型)。
一个常见的方法是:
time_t now = time(NULL);
struct tm *now_gmt = gmtime(&now);
然后,如果您对时间的特定格式不感兴趣,可以使用:
printf("%s", asctime(now_gmt));
或者您可以操作 struct tm
的字段 (tm_year
, tm_mon
, tm_mday
, tm_hour
, tm_min
, tm_sec
, tm_wday
, tm_yday
或 tm_isdst
---最后一个用于知道您是否处于夏季或冬季时间)
因此,在 POSIX 中所有问题都得到了解决。
最后,如果您有一个大量(64 位值)需要转换为 time_t,请使用以下方法进行转换:
#include <stdint.h>
...
int64_t val;
sscanf(the_string_value, "%lld", &val);
time_t my_time_t = (time_t) val;
我使用了强制类型转换,因为time_t
可能比int64_t
小,这可以避免编译器发出警告。
这将适用于64位和32位整数。一旦你将其转换为time_t
,所有上述内容仍然有效。
atoi
进行整数转换后再进行强制类型转换是没有意义的。最好使用strtoull
将其转换为unsigned long long
,然后再将其转换为time_t
。 - Weather Vaneint
,这并不是那么遥远。 - Weather Vanetime_t
值是“自纪元以来的秒数”,所以你的问题更多地是“是否有一种方法将自纪元以来的秒数的字符串表示转换为time_t
值”。而答案是“没有 - 没有一个函数明确地接受自纪元以来的秒数的字符串表示,并返回一个time_t
值”。 - Jonathan Lefflerstrtol
代替atoi()
,参见为什么不应该使用atoi()?。 - phuclv