localtime() 在 RTL8710 上偏移了大约 460,000 年
localtime() is off by about 460,000 years on RTL8710
我正在使用 RTL8710(运行 rustl8710,但就这个问题而言,这无关紧要,因为我所说的所有代码都是 C 代码)。 RTL8710 具有系统某些部分的专有库,包括 localtime
.
然而,localtime
像这样使用它时似乎偏离了大约 460,000 年(取自 the included NTP implementation):
long current_sec = 1543067026;
struct tm current_tm = *(localtime(¤t_sec));
此 returns 以下结构:
{tm_sec = 51,
tm_min = 36,
tm_hour = 15,
tm_mday = 25,
tm_mon = 8,
tm_year = -458682,
tm_wday = 2,
tm_yday = 267,
tm_isdst = -1515870811}
显然这是不正确的,它应该接近 2018 年 11 月 24 日 13:52:04 GMT。不过这不是随机的,因为时间似乎总是相差大约 2 小时零几分钟。
这里唯一值得注意的是代码使用默认系统 headers time.h
和 string.h
(这将来自 Ubuntu 18.10,我的 64 位例)。
我不知道 RealTek 真正使用的是什么 stdlib 库,但根据调试信息 (newlib/libc/time/lcltime.c
) 判断,我猜它是 newlib 的(修改过的?)版本。
代码使用了导致未定义行为的错误类型。1
// long current_sec = 1543067026;
time_t current_sec = 1543067026;
struct tm current_tm = *(localtime(¤t_sec));
更好的代码会在取消引用之前测试 localtime()
return 值。
struct tm *p = localtime(¤t_sec);
if (p) {
struct tm current_tm = *p;
...
1 错误的类型宽度如下所示。
int main() {
long current_sec = 1543067026;
struct tm current_tm = { .tm_sec = 51, .tm_min = 36, .tm_hour = 15, //
.tm_mday = 25, .tm_mon = 8, .tm_year = -458682, //
.tm_wday = 2, .tm_yday = 267, .tm_isdst = -1515870811 };
time_t t = mktime(¤t_tm);
printf("%16lx\n%16llx\n", current_sec, (unsigned long long) t);
}
输出
5bf95592
fffff2d55bf9a9f3
^^^^
许多位排列。我怀疑高位差异是由于 local_time()
引用了垃圾位,而低位差异是由于极端计算、OP 非同步发布代码和声称的输出,或者我和 OP 的标准库之间的差异。虽然 time_t
是无时区的,但我和 OP 的时区差异导致 locatime()/mktime()
差异。
我正在使用 RTL8710(运行 rustl8710,但就这个问题而言,这无关紧要,因为我所说的所有代码都是 C 代码)。 RTL8710 具有系统某些部分的专有库,包括 localtime
.
然而,localtime
像这样使用它时似乎偏离了大约 460,000 年(取自 the included NTP implementation):
long current_sec = 1543067026;
struct tm current_tm = *(localtime(¤t_sec));
此 returns 以下结构:
{tm_sec = 51,
tm_min = 36,
tm_hour = 15,
tm_mday = 25,
tm_mon = 8,
tm_year = -458682,
tm_wday = 2,
tm_yday = 267,
tm_isdst = -1515870811}
显然这是不正确的,它应该接近 2018 年 11 月 24 日 13:52:04 GMT。不过这不是随机的,因为时间似乎总是相差大约 2 小时零几分钟。
这里唯一值得注意的是代码使用默认系统 headers time.h
和 string.h
(这将来自 Ubuntu 18.10,我的 64 位例)。
我不知道 RealTek 真正使用的是什么 stdlib 库,但根据调试信息 (newlib/libc/time/lcltime.c
) 判断,我猜它是 newlib 的(修改过的?)版本。
代码使用了导致未定义行为的错误类型。1
// long current_sec = 1543067026;
time_t current_sec = 1543067026;
struct tm current_tm = *(localtime(¤t_sec));
更好的代码会在取消引用之前测试 localtime()
return 值。
struct tm *p = localtime(¤t_sec);
if (p) {
struct tm current_tm = *p;
...
1 错误的类型宽度如下所示。
int main() {
long current_sec = 1543067026;
struct tm current_tm = { .tm_sec = 51, .tm_min = 36, .tm_hour = 15, //
.tm_mday = 25, .tm_mon = 8, .tm_year = -458682, //
.tm_wday = 2, .tm_yday = 267, .tm_isdst = -1515870811 };
time_t t = mktime(¤t_tm);
printf("%16lx\n%16llx\n", current_sec, (unsigned long long) t);
}
输出
5bf95592
fffff2d55bf9a9f3
^^^^
许多位排列。我怀疑高位差异是由于 local_time()
引用了垃圾位,而低位差异是由于极端计算、OP 非同步发布代码和声称的输出,或者我和 OP 的标准库之间的差异。虽然 time_t
是无时区的,但我和 OP 的时区差异导致 locatime()/mktime()
差异。