C程序在Linux上使用GCC仅提供UTC时间作为本地时间

时间:2018-04-20 16:58:22

标签: c linux gcc timezone redhat

我有一个C程序,它运行在两个配置了相同时区的不同RHEL6服务器上。 C程序使用time.h中的时间函数。在其中一台服务器上正确确定本地时间,另一台服务器显示的UTC(默认)时间与配置的时区无关。

我已经尝试查看/etc/localtime的链接是否已损坏,但它是/usr/share/zoneinfo/<timezone>(在本例中为欧洲/柏林)的正确软链接。 我已使用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

所以它看起来像&#34;欧洲/柏林&#34;时间无法找到,因为显示UTC时间和时区&#34;欧洲&#34;无效。

正如我所说,其他机器上的输出/行为是预期的:

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

我的时区数据库是否可能在故障服务器上损坏?有人遇到类似问题并解决了吗?

1 个答案:

答案 0 :(得分:0)

我终于想通了,问题是libc.so库,它为其中一台机器编译不同,只用于Linux本身以外的一些C应用程序。这解释了为什么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

哪条路径用于获取时间/时区。您还可以检查ldd libc.so以查看链接器的默认路径。 如果路径与您的Linux系统配置不对应,请考虑重新编译C库以适合您的系统配置,或将$TZ='fullpathtotimezone'设置为修补程序/解决方法。