我的目标是在perl中处理广泛的日期,例如,453 CE,即"Atilla“去世的年份https://en.wikipedia.org/wiki/Attila。
现在,https://perldoc.perl.org/Time::Local指出了timelocal()在处理遥远年份方面的一个限制:
timelocal_modern()和timegm_modern() “时代”杂志第一次写“本地”时,通常的做法是将年份表示为两位数的数值,1999年为99,2001年为1。这引发了各种各样的问题(如果你很年轻的话,谷歌的"Y2K问题“),开发人员最终意识到这是一个糟糕的想法。
关于timelocal(),它说
警告:这些函数及其nocheck变体使用的年份值解释几乎肯定会导致代码中的错误,如果不是现在,那么在将来。强烈建议您不要在新代码中使用这些代码,如果可能的话,您应该将旧代码转换为使用*_posix或*_modern函数。
..。
年份值解释--这不适用于*_posix或*_modern函数。如果要确保代码老化时的行为一致,请使用这些导出。
因此,我想使用timelocal_modern()。但是下面的代码显示了这两个
timelocal()的行为,以及timelocal_modern()会生成一个异常。#!/usr/bin/perl
use strict; use warnings;
use Time::Local;
use POSIX qw(strftime);
print $^V; print "\n";
print "the year Atilla the Hun died:\n";
epochsTOyear(-47855224609);
my $modern;
eval{$modern=timelocal_modern(0,0,0,1,0,0)};
if(length $@)
{
print join('', '$modern=timelocal_modern(0,0,0,1,0,0) threw error: ', $@, "\n",);
}
else
{
print "modern==$modern\n";
}
yearTOformat1january(-1);
yearTOformat1january(0);
yearTOformat1january(2000);
yearTOformat1january(1);
yearTOformat1january(2001);
yearTOformat1january(1000);
yearTOformat1january(-999);
sub yearTOformat1january
{
my @base=(0,0,0,1,0,);
my $answer = timelocal( @base, $_[0]);
print join('', "year== ", $_[0], "\tso \tepoch seconds== ", $answer, "\tyields " , (strftime '%Y-%m-%d %a %H:%M:%S', localtime($answer)), "\n",);
}
sub epochsTOyear
{
my $yearresult=(strftime '%Y', localtime($_[0]));
print join('', "\t\tepoch seconds==", $_[0], "\tyields " , $yearresult, "\n",);
return $yearresult;
}我在电脑上得到的
~/u/kh/bin> perl --version
This is perl 5, version 18, subversion 4 (v5.18.4) built for darwin-thread-multi-2level
(with 2 registered patches, see perl -V for more detail)
Copyright 1987-2013, Larry Wall
Perl may be copied only under the terms of either the Artistic License or the
GNU General Public License, which may be found in the Perl 5 source kit.
Complete documentation for Perl, including FAQ lists, should be found on
this system using "man perl" or "perldoc perl". If you have access to the
Internet, point your browser at http://www.perl.org/, the Perl Home Page.
~/u/kh/bin> z.pl
v5.18.4
the year Atilla the Hun died:
epoch seconds==-47855224609 yields 0453
$modern=timelocal_modern(0,0,0,1,0,0) threw error: Undefined subroutine &main::timelocal_modern called at /Users/kpr/u/kh/bin/z.pl line 12.
year== -1 so epoch seconds== -2240506800 yields 1899-01-01 Sun 00:00:00
year== 0 so epoch seconds== 946702800 yields 2000-01-01 Sat 00:00:00
year== 2000 so epoch seconds== 946702800 yields 2000-01-01 Sat 00:00:00
year== 1 so epoch seconds== 978325200 yields 2001-01-01 Mon 00:00:00
year== 2001 so epoch seconds== 978325200 yields 2001-01-01 Mon 00:00:00
year== 1000 so epoch seconds== -30610206238 yields 1000-01-01 Wed 00:00:00
year== -999 so epoch seconds== -33734343838 yields 0901-01-01 Sat 00:00:00
~/u/kh/bin> 那么,我需要做什么才能得到timelocal_modern()
发布于 2021-08-18 17:54:00
您需要使用Time::Local 版本1.27或更高版本。
检查$Time::Local::VERSION以查看您当前的版本。
发布于 2021-08-18 19:52:49
默认情况下,本地不导出timelocal_modern。替换
use Time::Local;使用
use Time::Local qw( timelocal timelocal_modern );无论如何,我相信总是列出你们的进口商品是个好做法。它允许读者从每个函数的来源中找出。
您还可能需要升级时间::Local。timelocal_modern是在相对最近的1.27中添加的,但是Perl518.4附带了时间::local1.2300。
发布于 2021-08-18 22:25:34
解决办法是
> brew install perl
<snip>
> brew link --overwrite --dry-run perl
<snip>
> brew link --overwrite perl
Linking /usr/local/Cellar/perl/5.34.0... 2476 symlinks created.
> perl --version
This is perl 5, version 34, subversion 0 (v5.34.0) built for darwin-thread-multi-2level和下面的代码
#!/usr/local/bin/perl
use Time::Local;
use Time::Local qw( timelocal_posix timegm_posix );
use POSIX qw(strftime);
my $yearFROM1900;
unless(scalar @ARGV and $ARGV[0]=~/^[-]?\d+$/)
{
$yearFROM1900=0;
}
else
{
$yearFROM1900=$ARGV[0];
}
print "yearFROM1900==$yearFROM1900\n";
my $a;
$a=timelocal(0,0,0,1,0,$yearFROM1900);
print join('', (strftime '%Y', localtime($a)), ' <- ', $a, "\ttimelocal()\n",);
$a=timelocal_posix(0,0,0,1,0,$yearFROM1900);
print join('', (strftime '%Y', localtime($a)), ' <- ', $a, "\ttimelocal_posix()\n",);我们得到了两个非常不同的结果。如果我们给它一个数字-2470,即诗人萨福繁荣的日期和1900年的不同,那么timelocal和timelocal_posix的结果是一致的。但如果我们把它定为0岁,我们就会看到一个巨大的差别。
> z.pl $((-1900-570)) # poet Sappho
yearFROM1900==-2470
-570 <- -80154644400 timelocal()
-570 <- -80154644400 timelocal_posix()
> z.pl
yearFROM1900==0
2000 <- 946702800 timelocal()
1900 <- -2208970800 timelocal_posix()令我惊讶的是,在这台2019年的macOS计算机上,重新启动是不必要的。
https://stackoverflow.com/questions/68837117
复制相似问题