首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何在Perl5.18中调用timelocal_modern()?

如何在Perl5.18中调用timelocal_modern()?
EN

Stack Overflow用户
提问于 2021-08-18 17:45:04
回答 3查看 206关注 0票数 1

我的目标是在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()。但是下面的代码显示了这两个

  1. 具有远程日期的timelocal()的行为,以及
  2. 事实上,我试图调用timelocal_modern()会生成一个异常。
代码语言:javascript
复制
#!/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;
}

我在电脑上得到的

代码语言:javascript
复制
~/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()

EN

回答 3

Stack Overflow用户

发布于 2021-08-18 17:54:00

您需要使用Time::Local 版本1.27或更高版本

检查$Time::Local::VERSION以查看您当前的版本。

票数 4
EN

Stack Overflow用户

发布于 2021-08-18 19:52:49

默认情况下,本地不导出timelocal_modern。替换

代码语言:javascript
复制
use Time::Local;

使用

代码语言:javascript
复制
use Time::Local qw( timelocal timelocal_modern );

无论如何,我相信总是列出你们的进口商品是个好做法。它允许读者从每个函数的来源中找出。

您还可能需要升级时间::Local。timelocal_modern是在相对最近的1.27中添加的,但是Perl518.4附带了时间::local1.2300。

票数 0
EN

Stack Overflow用户

发布于 2021-08-18 22:25:34

解决办法是

代码语言:javascript
复制
> 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

和下面的代码

代码语言:javascript
复制
#!/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年的不同,那么timelocaltimelocal_posix的结果是一致的。但如果我们把它定为0岁,我们就会看到一个巨大的差别。

代码语言:javascript
复制
> 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计算机上,重新启动是不必要的。

票数 -1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/68837117

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档