微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

什么时候Perl脚本需要在调用`localtime`之前调用`tzset`?

我最近学到了 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以保持与某些环境的兼容性,还是现在已成为过去?

解决方法

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

Perl的本地时间调用localtime_r(3) internally,不需要调用tzset(3). Linux manpage建议:

According to POSIX.1-2004,localtime() is required to behave as though
tzset(3) was called,while localtime_r() does not have this
requirement. For portable code tzset(3) should be called before
localtime_r().

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

Local timezone information is used as though localtime() calls tzset()

虽然似乎有时间glibc didn’t adhere to that

As for any code which doesn’t call tzset all the time: this definitly
won’t change
. It’s far too expensive. And for what? The 0.000001%
of the people who take the laptops on a world tour and expect,e.g.,
syslog messages with dates according to the native timezone. This is
not justification enough. Just restart your machine.

虽然这确实发生了变化,但glibc现在确实就像调用tztime(3)一样,但仅适用于非重入本地时间,这可能不是你的Perl编译使用的.

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

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

原文地址:https://www.jb51.cc/Perl/171802.html

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐