在调用`localtime`之前,Perl脚本何时需要调用`tzset`?

时间:2016-07-08 23:21:12

标签: c perl timezone posix localtime

我最近学会了how to change the timezone returned by localtime in Perl

use POSIX qw(tzset);
print localtime . "\n";
$ENV{TZ} = 'America/Los_Angeles';
print localtime . "\n";
tzset;
print localtime . "\n";

输出

Wed Apr 15 15:58:10 2009
Wed Apr 15 15:58:10 2009
Wed Apr 15 12:58:10 2009

注意在调用tzset后小时的变化情况。

This is perl, v5.8.8 built for x86_64-linux-thread-multi

然而,在我的系统上,我得到了,

Fri Jul 8 19:00:51 2016
Fri Jul 8 16:00:51 2016
Fri Jul 8 16:00:51 2016

请注意,在我的系统上,小时更改而不调用tzset。这适用于Ubuntu和Illumos中的Perl的最新版本,以及Solaris 10上的Perl v5.8.8

因此,如果我的所有测试都表明tzset没有效果,那么为什么/其他系统需要tzset明确调用?我是否仍需要致电tzset以保持与某些环境兼容,或者它现在已成为过去?

1 个答案:

答案 0 :(得分:4)

TL; DR :从Perl v5.8.9(2011年发布)开始,在不再需要tzset时调用$ENV{TZ}

Perl的localtime来电localtime_r(3) internally,无需拨打tzset(3)Linux manpage建议:

  

根据POSIX.1-2004,localtime()需要表现得像   调用tzset(3),而localtime_r()没有这个   需求。对于可移植代码,应该先调用tzset(3)   则localtime_r()。

在旧的非多线程Perls中,或者如果在构建期间localtime_r(3)不可用,则使用localtime(3)。在这种情况下,调用tzset是不必要的,per POSIX

  

使用本地时区信息,就像localtime()调用tzset()

一样

虽然似乎有glibc didn't adhere to that

的时间
  

对于任何一直没有调用tzset的代码:这绝对是   不会改变。它太贵了。为了什么? 0.000001%   在世界巡演中拍摄笔记本电脑的人并期望,例如,   根据本机时区的日期系统日志消息。这是   没有足够的理由。只需重新启动你的机器。

确实更改了,而glibc现在的行为就像调用tztime(3)一样,但仅适用于非重入localtime,这可能不是您的Perl编译到的使用

有两个关于此问题的Perl错误报告:#26136#41591

作为修复,Perl现在decides at configuration time是否需要执行隐式tzset(3),这使得在用户代码中指定它是多余的。