Главное меню

Новости:

SMF - Just Installed!

Как производятся расчеты с датами?

Автор Siny, Март 15, 2024, 17:41

« назад - далее »

Siny

Как вычислить количество дней между двумя произвольными датами? (Например, от Октябрьской революции 7 ноября 1917 года до победы в Великой Отечественной войне 9 мая 1945 года? Или: сколько дней прожил человек от даты рождения до даты смерти?)
Какой вообще подход используется при операциях с датами (сложение или вычитание количества дней из любой даты, и т.п.)?
Примечание:
Вопрос про методы вычисления, а не про то, где найти машинку/программку/ф�ункцию, которая сама это сделает.
Например, на вопрос «как вычислить 12345 плюс 67890» не годится ответ «ввести числа в калькулятор, и прочитать ответ на дисплее».

Mahura

Так как тег вопроса стоит "программирование", а язык не указан, предложу вариант для языка программирования PHP.
В этом языке есть класс DateTime, с помощью которого очень удобно производить операции с датами. В нём уже учитываются и различное число дней в месяцах, и високосные года.
Например, эта функция будет вычислять разницу между датами, указанными в вопросе:
<?php
$date_1  = new DateTime('1917-11-07');
$date_2  = new DateTime('1945-05-09');
$created_time = $date_1->diff($date_2);
$cr_years     = $created_time->format('%y');
$cr_month     = $created_time->format('%m');
$cr_days      = $created_time->format('%d');
$cr_hours     = $created_time->format('%h');
$cr_minutes   = $created_time->format('%i');
$cr_seconds   = $created_time->format('%s');
$total_days   = $created_time->format('%a');
echo 'Между датами '.$date_1->format('d-m-Y H:i:s').' и '.$date_2->format('d-m-Y H:i:s').' прошло'.PHP_EOL;
echo $cr_years.' лет'.PHP_EOL;
echo $cr_month.' месяцев'.PHP_EOL;
echo $cr_days.' дней'.PHP_EOL;
echo $cr_hours.' часов'.PHP_EOL;
echo $cr_minutes.' минут'.PHP_EOL;
echo $cr_seconds.' секунд'.PHP_EOL;
echo 'или '.$total_days.' полных дней.';
?>
А результат вычислений будет таким:
Между датами 07-11-1917 00:00:00 и 09-05-1945 00:00:00 прошло
27 лет
6 месяцев
2 дней
0 часов
0 минут
0 секунд
или 10045 полных дней.
Отображение времени я добавил для демонстрации возможностей функции. Если оно не нужно, лишние строки можно удалить.
Если нужно узнать, какая дата будет через 100000 дней после 29 февраля 2000 года:
<?php
$date = new DateTime('2000-02-29');
$date->modify('+100000 day');
echo $date->format('d-m-Y');
?>
Результат будет: 14-12-2273
                                                                              

Udelar

Один из наиболее удобных и универсальных методов расчета дат является Rata Die - пересчет дат в количество дней, прошедших от 1 января 0001 года (начала нашей эры), и обратно.
RD(01.01.0001) = 1
RD(02.01.0001) = 2
...
RD(31.12.0001) = 365
RD(01.01.0002) = 366
RD(02.01.0002) = 367
...
RD(28.12.2021) = 738152
... и т.д.
Диапазон допустимых дат выходит за пределы года 9999.
Теоретически, эти расчеты можно расширить в сторону дат до нашей эры, используя отрицательные значения RD для дат ранее 1 января 0001 года, однако на практике это не используется, поскольку (1) не требуется в практических целях, и (2) усложняет формулы пересчета дат, по сравнению с датами только нашей эры.
(Кстати: именно этот подход используется в функциях работы с датами, встроенными в язык REXX, и возможно другие языки)
Этот метод достаточно удобен и понятен. Для его реализации разработаны несколько алгоритмов выполнения этих вычислений математическими формулами, без циклов итерации и без многочисленных проверок на "особенности" конкретного года или месяца (без множества IF-THEN-ELSE). К сожалению, в некоторых реализациях игнорируется невисокосность лет, кратных 3200, что несколько ограничивает их использование. Авторы считали, что поскольку они не доживут до первого из них - 3200 года, - то там уже хоть трава не расти. Примерно те же мысли были при вычислении дат в XX веке - годы считались от 00 до 99. Только к 2000 году неожиданно выяснилось, что многие вычисления после 1999 года не могут быть сделаны теми способами...
Преобразования даты
"Сдвиг" даты на число дней
ЧЧ.ММ.ГГГГ -> RD1
RD2 = RD1 + ЧислоДней
RD2 -> ЧЧ.ММ.ГГГГ  <== новая дата
Вычисление числа дней между датами
дата1 -> RD1
дата2 -> RD2
разница = RD2 - RD1
Параллельно упрощаются различные проверки, вроде допустимого значения даты. Если неправильную дату (такую как 29.02.2021, или любую несуществующую) преобразовать в значение RD, а затем преобразовать обратно в дату, то результат будет 01.03.2021; тогда, поскольку результат не совпадает с исходным значением, значит исходная дата была недопустимой.

Tiobyn

Каждая из двух дат переводится, на уровне машинных команд, в обычное целое число
из одного вычитается другое, всё просто... и факт, вроде бы, знакомый всем программистам.
число это (оба из двух) я-ся числом секунд с некой даты и момента времени,
погуглите, я не программист, наизусть не помню. Либо ждите, пока кто-то даст более развёрнутый ответ.