Как преобразовать заданное количество дней в годы, месяцы и дни в MySQL?
Я пытаюсь получить дату и продолжительность времени между кредитом и оплатил дата. Я использовал функции даты и времени PHP, но это не всегда точно. Как я могу сделать это точно в MySQL?
предположим, что две даты, взятый кредит дата
2009-05-24
и дата возврата кредита
2012-04-30
Я пишу запрос MySQL
SELECT DATEDIFF('2012-04-30', '2009-05-24') `total_days`;
возвращение 1072 дней, которое примерно 2 года, 11 месяцев, 12 дней.
пожалуйста, не отвечайте PHP-кодом, я уже пробовал. Вот код.
функция ниже использует PHP >= 5.3 функции и конвертировать дни в годы, месяцы и дни.
function date_interval($date1, $date2)
{
$date1 = new DateTime($date1);
$date2 = new DateTime($date2);
$interval = date_diff($date2, $date1);
return ((($y = $interval->format('%y')) > 0) ? $y . ' Year' . ($y > 1 ? 's' : '') . ', ' : '') . ((($m = $interval->format('%m')) > 0) ? $m . ' Month' . ($m > 1 ? 's' : '') . ', ' : '') . ((($d = $interval->format('%d')) > 0) ? $d . ' Day' . ($d > 1 ? 's' : '') : '');
}
функция ниже использует функции PHP >= 5.2 и преобразует дни в годы, месяцы и дни.
function date_interval($date1, $date2)
{
$diff = abs(strtotime($date2) - strtotime($date1));
$years = floor($diff / (365 * 60 * 60 * 24));
$months = floor(($diff - $years * 365 * 60 * 60 * 24) / (30 * 60 * 60 * 24));
$days = floor(($diff - $years * 365 * 60 * 60 * 24 - $months * 30 * 60 * 60 * 24) / (60 * 60 * 24));
return (($years > 0) ? $years . ' Year' . ($years > 1 ? 's' : '') . ', ' : '') . (($months > 0) ? $months . ' Month' . ($months > 1 ? 's' : '') . ', ' : '') . (($days > 0) ? $days . ' Day' . ($days > 1 ? 's' : '') : '');
}
4 ответов
главная проблема заключается в следующем:
- чтобы найти разницу между днями, вам нужно использовать
datediff()
-
datediff()
возвращает разницу в днях. - для того, чтобы преобразовать дней до даты, так что вы можете получить количество лет и т. д. Вам нужно использовать
from_days()
-
from_days()
не работает до 1582, цитата из документации:"использовать FROM_DAYS () с осторожностью на старых датах. Он не предназначен для использования со значениями, которые предшествуют появлению григорианского календаря (1582)"
минимум 1582, как это было, когда Европа превратилась из юлианского в Григорианский календарь.
0000-00-00 + 6 дней 0000-01-06, которое раньше чем 1582.
это фактически означает, что функции даты MySQL бесполезны для вас.
вы просите об этом сделать в MySQL "но". Поскольку вы не можете использовать функции даты, вам придется составить свой собственный. Это не будет быть точным. Сколько дней в году? Это, конечно, не всегда 365. Сколько дней в месяце?
Я бы настоятельно рекомендовал сделать это в PHP.
однако, поскольку вы твердо уверены, что не хотите этого делать, вам придется обмануть.
добавить дату 1600-01-01 в все. Затем снимите 1600 лет, 1 месяц и 1 день из вашего ответа в конце. Я использую эту дату только потому, что она больше 1582, и это хорошее круглое число. Все будет работать на самом деле, но чем раньше, тем лучше, чтобы вы не столкнулись с проблемами.
Предположим, мы построили следующую таблицу:
create table dates (a date, b date);
insert into dates
values ( str_to_date('2012-04-30','%Y-%m-%d')
, str_to_date('2012-04-24','%Y-%m-%d')
);
insert into dates
values ( str_to_date('2012-04-30','%Y-%m-%d')
, str_to_date('2009-05-24','%Y-%m-%d')
);
следующий запрос получит то, что вы хотите:
select extract(year from from_days(days)) - 1600
, extract(month from from_days(days)) - 1
, extract(day from from_days(days)) - 1
from ( select to_days(a) - to_days(b) +
to_days(str_to_date('1600-01-01', '%Y-%m-%d')) as days
from dates ) as b
вот Скрипка SQL, чтобы доказать это.
раз опять же, это действительно довольно hacky и не рекомендуется.
используйте MySQL TIMESTAMPDIFF()
функция:
SELECT TIMESTAMPDIFF(YEAR
, '2009-05-24'
, '2012-04-30'
) AS Years,
TIMESTAMPDIFF(MONTH
, '2009-05-24'
+ INTERVAL TIMESTAMPDIFF(YEAR, '2009-05-24', '2012-04-30') YEAR
, '2012-04-30'
) AS Months,
TIMESTAMPDIFF(DAY
, '2009-05-24'
+ INTERVAL TIMESTAMPDIFF(YEAR, '2009-05-24', '2012-04-30') YEAR
+ INTERVAL TIMESTAMPDIFF(YEAR, '2009-05-24', '2012-04-30') MONTH
, '2012-04-30'
) AS Days
см. На sqlfiddle.
я использовал этот:
SELECT TIMESTAMPDIFF(YEAR
, '2010-08-29'
, '2014-09-18'
) AS Years,
TIMESTAMPDIFF(MONTH
, '2010-08-29'
+ INTERVAL TIMESTAMPDIFF(YEAR, '2010-08-29', '2014-09-18') YEAR
, '2014-09-18'
) AS Months,
TIMESTAMPDIFF(DAY
, '2010-08-29'
+ INTERVAL TIMESTAMPDIFF(MONTH, '2010-08-29', '2014-09-18') MONTH
, '2014-09-18'
) AS Days