在调用`localtime`之前,Perl脚本何时需要调用`tzset`?
最近我学习了如何在Perl中更改localtime
返回的时区。
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
以保持与某些环境的兼容性,还是现在已成为过去?
TL; DR :在改变$ENV{TZ}
不再需要调用tzset
Perl v5.8.9(2011年发布)。
Perl的localtime
内部调用localtime_r(3)
,这不需要调用tzset(3)
。 Linux的manpage建议:
根据POSIX.1-2004,localtime()需要表现得像tzset(3)被调用,而localtime_r()没有这个要求。 对于便携式代码tzset(3)应该在localtime_r()之前调用。
在较旧的非多线程Perls中,或者如果localtime_r(3)
在构建期间不可用,则会使用localtime(3)
。 在这种情况下,根据POSIX,对tzset
的调用是不必要的:
使用本地时区信息就像localtime()调用tzset()
尽管似乎有些时候glibc并不坚持:
至于任何不总是调用tzset的代码: 这个definitly不会改变 。 这太贵了。 什么? 在世界巡回演唱会中使用笔记本电脑的人中有0.000001%会期望使用日期根据本地时区的系统日志消息。 这不够合理。 只需重新启动机器。
这虽然没有改变和glibc现在不采取行动,就好像tztime(3)
被调用,但仅限于非重入localtime
这可能不是什么你的Perl编译使用。
关于这个问题有两个Perl错误报告:#26136和#41591。
作为一种修正,Perl现在在配置时决定是否需要执行隐式tzset(3)
,这使得在用户代码中指定它是多余的。
上一篇: When does a Perl script need to call `tzset` before calling `localtime`?