c - mktime 返回不正确的值

标签 c time mktime

我想在微 Controller 上使用 mktime(或者至少使用 32 位宽的时间戳)。我从 avr libc source files 添加了所需的文件(在 Atmel Studio 7 中,时间函数不可用),没有更改算法。但是对于 2016.06.08.23:34:00 (UTC+1, EU dst),mktime 返回 518736960,但它应该返回 1465425240.

set_zone(ONE_HOUR);
set_dst(eu_dst);
struct tm myTime;
myTime.tm_sec = 0;
myTime.tm_min = 36;
myTime.tm_hour = 23;
myTime.tm_mday = 8;
myTime.tm_mon = 5;
myTime.tm_year = 116;
myTime.tm_isdst = ONE_HOUR;
time_t tim = mktime(&myTime);

我做错了什么?这些功能应该可以正常工作。

最佳答案

518736960 对应于 Unix 纪元时间 09 Jun 1986 21:36:00;在我看来,这个实现好像使用了不同的纪元,从 2000 年 1 月 1 日开始,而不是 1970 年 1 月 1 日。

时差归因于 TZ 和 DST 偏移量。日期相差一个是由于 2000 年不是闰年,而 1970 年是闰年。


编辑:

文档 here明确指出纪元开始是 2000 年:

Though not specified in the standard, it is often expected that time_t is a signed integer representing an offset in seconds from Midnight Jan 1 1970... i.e. 'Unix time'. This implementation uses an unsigned 32 bit integer offset from Midnight Jan 1 2000. The use of this 'epoch' helps to simplify the conversion functions, while the 32 bit value allows time to be properly represented until Tue Feb 7 06:28:15 2136 UTC. The macros UNIX_OFFSET and NTP_OFFSET are defined to assist in converting to and from Unix and NTP time stamps.

既没有纪元标准,也没有time_t 的特定基础宽度或符号性。但是,如果您使用 localtime() 往返 mktime() 的结果,例如使用相同的库,它将产生正确的结果。一个库或系统的 time_t 值不需要与另一个兼容,因此在系统之间交换 time_t 值会出现一些问题。

在这种情况下,您可以通过添加 UNIX_OFFSETNTP_OFFSET 转换为公认的事实标准,并在必要时确保在接收系统上执行任何相应的调整原则是类似network byte order的原理 例如,通过使用约定的中间表示在具有不同终结性的系统之间交换数据(这恰好也是交换 time_t 时要考虑的事情)。

通常交换指定格式的字符串(例如 ISO 8601 )会更简单,以避免纪元、数据类型和字节序差异。另一方面,字符串表示形式的转换比纯算术操作的成本更高。

关于c - mktime 返回不正确的值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37714019/

相关文章:

Linux 上 mktime 的混淆行为?

c++ - LIBC 的 mktime 函数对相同的输入返回不同的值

c - fseek 从一行到另一行

将指针更改为指向堆栈地址而不是堆地址

PHP Mysql获取时间范围之间的差距

c - C 中的 localtime() 和 gmtime() 有什么区别?

c++ - 获取自 C++ 纪元以来的天数(跨平台)

c - 有没有更好的方法来计算 (n * 8 + 3)/5?

c - 读取结构的连续数组元素并立即打印它直到它到达 c 中的文件末尾

android - getYear(), getMonth(), getDay 在 Calendar 中被弃用了,那该用什么?