Perl函数localtime在1964年到1967年间给出了不正确的值

Perl函数localtime在1964年到1967年间给出了不正确的值,perl,localtime,Perl,Localtime,我从Perl中的localtime函数中得到了一些奇怪的值。下面是一些我得到不正确值的代码 特别是,此代码用于确定每年第一个工作日 #!/usr/bin/perl use strict 'vars'; use Time::Local; use POSIX qw(strftime); mytable(); sub mytable { print "Year" . " "x4 . "Jan 1st (localtime)" . " "x4 . "Jan 1st (Gauss)\n";

我从Perl中的localtime函数中得到了一些奇怪的值。下面是一些我得到不正确值的代码

特别是,此代码用于确定每年第一个工作日

#!/usr/bin/perl
use strict 'vars';
use Time::Local;
use POSIX qw(strftime);

mytable();

sub mytable {
   print "Year" . " "x4 .  "Jan 1st (localtime)" . " "x4 . "Jan 1st (Gauss)\n";
   foreach my $year ( 1964 .. 2017 )
     {
       my $janlocaltime = evalweekday( 1,1,$year);
       my $jangauss     = gauss($year);
       my $diff = $jangauss - $janlocaltime;
       printf "%4s%10s%-12s ",$year,"",$janlocaltime;
       printf "%12s",$jangauss;
       printf " <----- ERROR: off by %2s", $diff if ( $diff != 0 );
     print "\n";
     }
}

sub evalweekday {
   ## Using "localtime"
   my ($day,$month,$year) = @_;
   my $epoch   =  timelocal(0,0,0, $day,$month-1,$year-1900);
   my $weekday = ( localtime($epoch) ) [6];
   return $weekday;
 }

sub gauss {
   ## Alternative approach
   my ($year) = @_;
   my $weekday =
     (  1 + 5 * ( ( $year - 1 ) % 4 )
      + 4 * ( ( $year - 1 ) % 100 )
      + 6 * ( ( $year - 1 ) % 400 )
    ) % 7;
   return $weekday;
 }
我不确定它是否相关,但我的操作系统是macOS Sierra版本10.12.3

我已经通读了文档,但是我没有看到关于1968年之前返回的值的任何内容(或者说我是瞎的)。我也尝试过做一个网络搜索,但除了对数组值和一年中的月数和日数的典型误解之外,我没有找到任何东西


有人能帮我解释一下我的错误吗?或者,如果这是我的Perl版本的一个问题,请告诉我可以做些什么来解决它。

这可能与Time::Local中负历元值的处理方式有关。看看

在我的Linux机器(Perl5.20)上,您的代码很好地演示了这个问题。如果打印出收到的历元值,您将看到问题,即
timelocal
返回的历元变大,而不是变负:

Year       Epoch Jan 1st (localtime)     Jan 1st (Gauss)
1964  2966342400 2                       3 <----- ERROR: off by  1
1965  2997964800 4                       5 <----- ERROR: off by  1
1966  3029500800 5                       6 <----- ERROR: off by  1
1967  3061036800 6                       0 <----- ERROR: off by -6
1968   -63185400 1                       1
1969   -31563000 3                       3
1970      -27000 4                       4
1971    31509000 5                       5
1972    63045000 6                       6

6=Saturday
与Wikipedian视图相匹配:

我删除了函数调用前面的
&
,因为这些不再是必需的(至少在过去10年中)。
This is perl 5, version 18, subversion 2 (v5.18.2) 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.
Year       Epoch Jan 1st (localtime)     Jan 1st (Gauss)
1964  2966342400 2                       3 <----- ERROR: off by  1
1965  2997964800 4                       5 <----- ERROR: off by  1
1966  3029500800 5                       6 <----- ERROR: off by  1
1967  3061036800 6                       0 <----- ERROR: off by -6
1968   -63185400 1                       1
1969   -31563000 3                       3
1970      -27000 4                       4
1971    31509000 5                       5
1972    63045000 6                       6
use DateTime;
my $dt = DateTime->new(
    year   => 1966, # Real Year
    day    => 1,    # 1-31
    month  => 1,    # 1-12
    hour   => 0,    # 0-23
    second => 0,    # 0-59
);
print $dt->dow . "\n";

6