Как получить правильный год, месяц и день в датировке функции firebird, включая високосные годы - PullRequest
1 голос
/ 25 января 2020

Мне нужно расширение решения, которое я получил, и оно видно по ссылке Как получить правильный год, месяц и день в функции firebird datediff . Я думал, что нашел правильное решение, но оказалось, что результаты, которые я получаю, отличаются от тех, которые подсчитываются вручную в течение нескольких дней. Анализ показал, что причиной этого различия были високосные годы. У кого-нибудь есть идея, как обновить этот запрос, чтобы включить високосные годы в подсчет дат?

У меня есть sql запрос для Ливия, например:

SELECT
KP3.id_contact 
, (KP3.D2-KP3.D1) / (12*31) AS Y
, ((KP3.D2-KP3.D1) - ((KP3.D2-KP3.D1) / (12*31)) * 12 * 31) / 31 AS M
, CAST(MOD((KP3.D2-KP3.D1) - (((KP3.D2-KP3.D1) / (12*31)) * 12 * 31), 31) AS INTEGER) AS D
FROM
(SELECT
KP2.id_contact, SUM(KP2.D1) AS D1, SUM(KP2.D2) AS D2
FROM
    (
    SELECT
    KP.id_contact, DATEDIFF(MONTH, KP.DATE_FROM, KP.DATE_TO) / 12 AS Y, CAST(MOD(DATEDIFF(MONTH, KP.DATE_FROM, KP.DATE_TO), 12) AS INTEGER) AS M 
    , EXTRACT(YEAR FROM KP.DATE_FROM)*12*31+EXTRACT(MONTH FROM KP.DATE_FROM)*31+EXTRACT(DAY FROM KP.DATE_FROM) D1
    , EXTRACT(YEAR FROM KP.DATE_TO)*12*31+EXTRACT(MONTH FROM KP.DATE_TO)*31+EXTRACT(DAY FROM KP.DATE_TO) D2 
    FROM
    KP  
    ) AS KP2
GROUP BY KP2.id_contact
) AS KP3

Например, у меня есть интервал с 2011-11-02 по 2014-08-31. Когда я использую этот запрос, я получаю результат 2Y 9M 29D. Но когда я вычисляю это под рукой, я получаю результат 2Y 9M 30D. Это один день, потому что в 2012 году 366 дней, а не 365, потому что 2012 год високосный.

...