道歉,如果这是一个非常简单的问题,但我有兴趣尝试找到准确的答案,而不仅仅是一个“四舍五入”的答案。
我的问题是:我知道有人在2008年3月18日是27.12(随机例子)。我怎样才能计算出他最近的出生日期。年龄总是作为实数提供给两个小数点。
答案 0 :(得分:2)
由于四舍五入,通过简单分数计算的解决方案是1981-02-03和前一天。正如eumiro所说,1/100年的分辨率不够准确,所以它可能仍然会在实际日期的一两天内停止。
use DateTime qw();
use POSIX qw(modf);
my $date = DateTime->new(year => 2008, month => 3, day => 18); # 2008-03-18
my $age = 27.12; # 27.12
my ($days, $years) = modf $age; # (0.12, 27)
$days *= 365.25; # 43.83
# approx. number of days in a year, is accurate enough for this purpose
$date->clone->subtract(years => $years, days => $days); # 1981-02-03
$date->clone->subtract(years => $years, days => 1 + $days); # 1981-02-02
答案 1 :(得分:0)
use strict;
use Time::Local;
my $now = timelocal(0, 0, 12, 18, 3-1, 2008);
my $birthday = $now - 27.12 * 365.25 * 86400;
print scalar localtime $birthday;
返回Mon Feb 2 22:04:48 1981
。
您的精确度为0.01年,大约为3天,因此您甚至无法涵盖所有生日。
我的方法并没有很好地涵盖闰年,但你无法真正用它们来计算。想象一下2008年3月1日。在此日期之前的“1年1天”是什么日期? 2007年2月28日或2007年2月29日不存在?
答案 2 :(得分:0)
use strict;
use warnings;
use 5.010;
use Time::Piece;
use Time::Seconds;
my ($date, $age) = ('2008-03-18', 27.12);
my $birthday = Time::Piece->strptime($date, '%Y-%m-%d') - $age*ONE_YEAR;
say $birthday->ymd();
由于年龄不准确(1/100年),这将在实际生日的几天内到达。
答案 3 :(得分:0)
允许更高精度的方法只是利用现有的MySQL日期/时间函数。如果在MySQL内部工作,您可以通过在TO_SECONDS()转换中将两个日期中的每一个转换为秒,然后将结果操作到所需的精度,来精确计算年龄。在这些情况下,日期采用'yyyy-mm-dd hh:mm:ss'格式,假设一年的平均长度为365.242天。
ROUND((TO_SECONDS(AnyDateTime) - TO_SECONDS(DateOfBirth))/(365.242 * 60 * 60 * 24),3)作为年龄, 例如:
ROUND((TOSECONDS('2013-01-01 00:00:00') - TO_SECONDS('1942-10-16')/(365.242*60*60*24),3) as AGE --> 70.214
或者你可以使用DATEDIFF()转换,它提供了几天的答案:
ROUND(DATEDIFF('2013-01-01 00:00:00','1942-10-16')/365.242,3) AS age --> 70.214