我的脚本计算两个日期之间的天数差异。但是,我一直遇到错误。该解决方案必须适用于所有操作系统。建议在 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 系统。
从文档中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
。
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句