代码之家  ›  专栏  ›  技术社区  ›  J. Doe Aura

Perl-计算MS Windows和Linux上两个日期之间的天数差

  •  0
  • J. Doe Aura  · 技术社区  · 7 年前

    我的脚本计算两个日期之间的天数差。然而,我总是遇到错误。该解决方案必须适用于所有操作系统。建议在UNIX时代进行此操作,但如果不可能,则可能会有另一种解决方案。

    我试过:
    Time::ParseDate -在MS Windows上不工作
    Time::Local -不适用于本月31日之后的日期

    示例代码:

    #!/usr/bin/perl -w
    use strict;
    use Time::Local;
    use POSIX;
    
    sub toepoch {
      my @a = split /[- :]/, $_[0];
      $a[0] =~ s/^.{2}//;
      if (! defined $a[5]) {
        $a[5] = 00
      }
      my $b = timelocal($a[5], $a[4], $a[3], $a[2], $a[1], $a[0]);
      return $b;
    }
    
    my $days = sprintf("%d",(&toepoch('2018-03-31 11:00') - &toepoch('2018-04-02 11:00') / 86400));
    print $days;
    

    输出: Day '31' out of range 1..30 at epoch.pl line 12.

    接下来我应该签入哪个模块?我提醒您,该解决方案必须在UNIX和MS Windows系统上运行。

    1 回复  |  直到 7 年前
        1
  •  4
  •   Silvar    7 年前

    从文档中 Time::Local :

    值得特别注意的是 提供的值。月日的值为实际值 天(即1..31),而月是自1月以来的月数 (0..11)。这与从 “localtime()”和“gmtime()”。

    因此,通过提供 timelocal 阵列 (0, 00, 11, 31, 03, 18) 您正在尝试使用第4个月的第31天,因为4月份只有30天,所以它不起作用。如果错误消息中包含它假设的月份!

    进行转换时,需要注意将月份值保持在0以内。。11并相应调整年份。

    (或者,您可以使用 timelocal_nocheck() 允许输入第1个月,并让函数转换到上一年。虽然如果你 使用该功能,您会遇到一个更难追踪的错误,因为它会自动将4月31日转换为5月1日,您不知道为什么时差只有1天。)

    其次,计算行中有一个放错位置的括号,因此只需将后一次除以86400。

    我的编辑代码:

    use strict;
    use warnings;
    
    use Time::Local;
    use POSIX;
    
    sub toepoch {
        my @a = split /[- :]/, $_[0];
        $a[0] =~ s/^.{2}//;
        if (! defined $a[5]) {
            $a[5] = 00
        }
        --$a[1];
        if ($a[1] < 0) {
            --$a[0];
            $a[1] += 12;
        }
        my $b = timelocal($a[5], $a[4], $a[3], $a[2], $a[1], $a[0]);
        return $b;
    }
    
    my $days = sprintf("%d",(&toepoch('2018-03-31 11:00') - &toepoch('2018-04-02 11:00')) / 86400);
    print $days;
    

    输出:

    -2
    

    编辑:

    我想你知道在使用格式时你在做什么 %d 对于值-它将值截断为下一个整数,这意味着如果您有日期

    2018-03-31 11:00
    2018-04-02 10:59
    

    也就是说,距离2天只差1分钟,您的程序会将时差报告为“-1”。

    要四舍五入到最接近的整数,请使用以下格式 %.0f 相反