C 程序使用 GCC 在 Linux 上仅提供 UTC 时间作为本地时间
C program delivers only the UTC time as localtime on Linux using GCC
我有一个 C 程序 运行 在配置了相同时区的两个不同的 RHEL6 服务器上运行。 C 程序使用 time.h
中的时间函数。在其中一台服务器上正确确定了本地时间,在另一台服务器上显示的 UTC(默认)时间独立于配置的时区。
我试着看看 link 到 /etc/localtime
是否坏了,但它是一个正确的 softlink 到 /usr/share/zoneinfo/<timezone>
(在这种情况下 Europe/Berlin).
我用 zdump
检查了时区文件,文件的内容是正确的。使用 date
也可以正确显示系统的时区和时间。在我的 bash 或其他任何地方都没有 $TZ
变量的定义!
作为附加测试,我有 运行 以下带有和不带有 $TZ
变量的代码:
::time_t aclock;
::tm tm_tmp;
::tm *newtime;
setenv("TZ", "Europe/Berlin", 1);
tzset();
::time( &aclock );
newtime = ::localtime_r( &aclock, &tm_tmp );
printf("\nDEBUG TIME: %d ", aclock);
printf("\nDEBUG TIMEZONE: %s \n", newtime->tm_zone);
printf("DEBUG HOUR: %d \n", newtime->tm_hour);
使用上面的代码并以不同的方式设置 TZ 参数,我在 故障 服务器上得到以下输出,假设此时服务器时间是 Europe/Berlin, CEST
:
without setenv:
DEBUG TIME: 1524241319
DEBUG TIMEZONE: UTC
DEBUG HOUR: 16
setenv("TZ", "Europe/Berlin", 1);
DEBUG TIME: 1524241319
DEBUG TIMEZONE: Europe
DEBUG HOUR: 16
setenv("TZ", "/etc/localtime", 1);
DEBUG TIME: 1524241319
DEBUG TIMEZONE: CEST
DEBUG HOUR: 18
看来找不到 "Europe/Berlin" 时间,因为显示的是 UTC 时间,而时区 "Europe" 无效。
正如我所说,另一台机器上的输出/行为是预期的:
without setenv:
DEBUG TIME: 1524241711
DEBUG TIMEZONE: CEST
DEBUG HOUR: 18
setenv("TZ", "Europe/Berlin", 1);
DEBUG TIME: 1524241711
DEBUG TIMEZONE: CEST
DEBUG HOUR: 18
setenv("TZ", "/etc/localtime", 1);
DEBUG TIME: 1524241711
DEBUG TIMEZONE: CEST
DEBUG HOUR: 18
P.S。两台机器上使用相同的 gcc 版本 4.4.7。
有没有可能是我的时区数据库在故障服务器上损坏了?有人遇到过类似问题并解决了吗?
我终于弄清楚,问题出在 libc.so
库,它针对其中一台机器进行了不同的编译,并且只用于某些 C 应用程序,linux 他自己除外。这解释了为什么 date
提供了 wright 输出但 C 程序没有。
使用 ldd libc.so
我发现链接器也被设置为默认路径 /home/mqm/lib
,这不适合我的服务器 /home/mqm/lib/lib/ld-linux-x86-64.so.2 => /lib64/ld-linux-x86-64.so.2
。要恢复,这里是完整的解决方案:
问题:您的 Linux 系统使用 date
或某些应用程序提供正确的日期和时间,但使用 C 程序输出错误。
解决方法:确保你的代码没有编程错误后,再用
检查
strace -e trace=open,close,read,write,connect,accept yourCProgram
哪个路径用于获取time/timezone。您还可以检查 ldd libc.so
以查看链接器的默认路径在哪里。
如果路径与您的 linux 系统配置不对应,请考虑重新编译 C 库以适合您的系统配置或将 $TZ='fullpathtotimezone'
设置为修补程序/解决方法。
我有一个 C 程序 运行 在配置了相同时区的两个不同的 RHEL6 服务器上运行。 C 程序使用 time.h
中的时间函数。在其中一台服务器上正确确定了本地时间,在另一台服务器上显示的 UTC(默认)时间独立于配置的时区。
我试着看看 link 到 /etc/localtime
是否坏了,但它是一个正确的 softlink 到 /usr/share/zoneinfo/<timezone>
(在这种情况下 Europe/Berlin).
我用 zdump
检查了时区文件,文件的内容是正确的。使用 date
也可以正确显示系统的时区和时间。在我的 bash 或其他任何地方都没有 $TZ
变量的定义!
作为附加测试,我有 运行 以下带有和不带有 $TZ
变量的代码:
::time_t aclock;
::tm tm_tmp;
::tm *newtime;
setenv("TZ", "Europe/Berlin", 1);
tzset();
::time( &aclock );
newtime = ::localtime_r( &aclock, &tm_tmp );
printf("\nDEBUG TIME: %d ", aclock);
printf("\nDEBUG TIMEZONE: %s \n", newtime->tm_zone);
printf("DEBUG HOUR: %d \n", newtime->tm_hour);
使用上面的代码并以不同的方式设置 TZ 参数,我在 故障 服务器上得到以下输出,假设此时服务器时间是 Europe/Berlin, CEST
:
without setenv:
DEBUG TIME: 1524241319
DEBUG TIMEZONE: UTC
DEBUG HOUR: 16
setenv("TZ", "Europe/Berlin", 1);
DEBUG TIME: 1524241319
DEBUG TIMEZONE: Europe
DEBUG HOUR: 16
setenv("TZ", "/etc/localtime", 1);
DEBUG TIME: 1524241319
DEBUG TIMEZONE: CEST
DEBUG HOUR: 18
看来找不到 "Europe/Berlin" 时间,因为显示的是 UTC 时间,而时区 "Europe" 无效。
正如我所说,另一台机器上的输出/行为是预期的:
without setenv:
DEBUG TIME: 1524241711
DEBUG TIMEZONE: CEST
DEBUG HOUR: 18
setenv("TZ", "Europe/Berlin", 1);
DEBUG TIME: 1524241711
DEBUG TIMEZONE: CEST
DEBUG HOUR: 18
setenv("TZ", "/etc/localtime", 1);
DEBUG TIME: 1524241711
DEBUG TIMEZONE: CEST
DEBUG HOUR: 18
P.S。两台机器上使用相同的 gcc 版本 4.4.7。
有没有可能是我的时区数据库在故障服务器上损坏了?有人遇到过类似问题并解决了吗?
我终于弄清楚,问题出在 libc.so
库,它针对其中一台机器进行了不同的编译,并且只用于某些 C 应用程序,linux 他自己除外。这解释了为什么 date
提供了 wright 输出但 C 程序没有。
使用 ldd libc.so
我发现链接器也被设置为默认路径 /home/mqm/lib
,这不适合我的服务器 /home/mqm/lib/lib/ld-linux-x86-64.so.2 => /lib64/ld-linux-x86-64.so.2
。要恢复,这里是完整的解决方案:
问题:您的 Linux 系统使用 date
或某些应用程序提供正确的日期和时间,但使用 C 程序输出错误。
解决方法:确保你的代码没有编程错误后,再用
检查strace -e trace=open,close,read,write,connect,accept yourCProgram
哪个路径用于获取time/timezone。您还可以检查 ldd libc.so
以查看链接器的默认路径在哪里。
如果路径与您的 linux 系统配置不对应,请考虑重新编译 C 库以适合您的系统配置或将 $TZ='fullpathtotimezone'
设置为修补程序/解决方法。