c - Perl 脚本在调用 'localtime' 之前什么时候需要调用 '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:从 Perl v5.8.9(2011 年发布)开始,不再需要在更改$ENV{TZ}时调用tzset


Perl 的localtime在内部调用localtime_r(3),调用tzset(3)不需要。Linux 手册页建议:

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

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

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

尽管似乎有些时候glibc并没有坚持这一点:

至于任何不一直调用 tzset 的代码:这肯定是 不会改变。 太贵了。 为了什么? 的 0.000001% 携带笔记本电脑进行世界巡回演出并期待的人,例如, 系统日志消息,其日期根据本机时区。 这是 不够理由。 只需重新启动计算机即可。

不过,这确实发生了变化,glibc 现在确实表现得好像调用了tztime(3),但仅适用于非重入localtime这可能不是您的 Perl 编译使用的内容。

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

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

相关内容

  • 没有找到相关文章

最新更新