Рассчитать дату рождения от возраста на конкретную дату [MySQL или Perl] - PullRequest
1 голос
/ 25 января 2011

Извиняюсь, если это действительно простой вопрос, но я заинтересован в том, чтобы попытаться найти точный ответ, а не просто «округленный» ответ.марта 2008 года (случайный пример).Как я могу рассчитать, в ближайшем приближении, его дату рождения.Возраст всегда указывается в виде действительного числа с двумя десятичными знаками.

Ответы [ 4 ]

2 голосов
/ 25 января 2011

Решения с помощью простого дробного расчета: 1981-02-03 и накануне, из-за округления.Как сказал Евмиро, разрешение 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
0 голосов
/ 06 октября 2013

Метод, который допускает большую точность, просто использует преимущества существующих функций даты / времени MySQL.Если вы работаете внутри MySQL, вы можете с большой точностью вычислить возраст, преобразовав каждую из двух дат в секунды в преобразовании TO_SECONDS (), а затем манипулируя результатами с желаемой точностью.В этих случаях даты имеют формат «гггг-мм-дд чч: мм: сс», и предполагается, что год имеет среднюю длину 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
0 голосов
/ 25 января 2011

ответ eumiro делает свое дело; следующее, используя модуль Time :: Piece (в комплекте с Perl начиная с 5.10), возможно, более удобен в обслуживании.

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 года) в возрасте.

0 голосов
/ 25 января 2011
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 дня, поэтому вы даже не можете охватить все дни рождения.

Мой метод не очень хорошо охватывает високосные годы, но вы не можете точно рассчитать с ними.Представь себе 01 марта 2008 года.Какая дата была «1 год и 1 день» до этой даты?28 февраля 2007 или несуществующий 29 февраля 2007?

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...