为什么这个perl DateTime的计算会产生意料之外的结果?

7
#!/usr/bin/perl
use DateTime;

$a = DateTime->new(year=>1952,month=>10,day=>21);
$b = DateTime->new(year=>2015,month=>10,day=>31);

$dif = $b-$a;

print $dif->years() ." ". $dif->months() ." ". $dif->days();
# result: 63 0 3

为什么会是三天?我的期望值是63010。

#!/usr/bin/perl
use DateTime;

$a = DateTime->new(year=>1952,month=>11,day=>1);
$b = DateTime->new(year=>2015,month=>10,day=>31);

$dif = $b-$a;

print $dif->years() ." ". $dif->months() ." ". $dif->days();
# result 62 11 2

我期望的结果是62年11月31日左右。

我正在尝试进行一些基本的出生日期与年龄的计算。月份和年份似乎按照我的预期工作,但日期似乎不可预测。我已经阅读了CPAN文档,但仍然不理解。


6
注意离题:最好不要使用变量 $a 和 $b,因为它们在 Perl 中是特殊的。 - red0ct
1个回答

11

$dif->years$diff->months和特别是$diff->days并不像你期望的那样工作。请参考DateTime::Duration文档...

These methods return numbers indicating how many of the given unit the object represents, after having done a conversion to any larger units. For example, days are first converted to weeks, and then the remainder is returned. These numbers are always positive.

Here's what each method returns:

$dur->years()       == abs( $dur->in_units('years') )
$dur->months()      == abs( ( $dur->in_units( 'months', 'years' ) )[0] )
$dur->weeks()       == abs( $dur->in_units( 'weeks' ) )
$dur->days()        == abs( ( $dur->in_units( 'days', 'weeks' ) )[0] )
如果你觉得这很令人困惑,我也是这样的。
你需要的是in_units
# 63 0 10
say join " ", $dif->in_units('years', 'months', 'days');

1
有趣。因此,该软件包的默认假设是对周数感兴趣。对于天数的默认结果是通常预期的“模7”。 - Jeff Y
1
非常好的回答。我真的很感激你将相关文档加粗了。 - Fletcher Moore
@JeffY 是的,DateTime 喜欢固定长度单位。日期计算问题在 How DateTime Math Works 中有所涉及。日历计算很复杂。 - Schwern
@FletcherMoore 谢谢。 :) 我最近才发现你可以这样做。 - Schwern

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接