Подтвердить что ты не робот

Разница в месяцах между датами в MySQL

Я рассчитываю рассчитать количество месяцев между двумя полями времени.

Есть ли лучший способ, чем получить временную метку unix и деление на 2 592 000 (в секундах) и округление в MySQL?

4b9b3361

Ответ 1

Функция DATEDIFF может дать вам количество дней между двумя датами. Что более точно, поскольку... как вы определяете месяц? (28, 29, 30 или 31 день?)

Ответ 2

Месяц-разница между любыми двумя датами:

Я удивлен, что это еще не упоминалось:

Посмотрите на функцию TIMESTAMPDIFF() в MySQL.

Что вы можете сделать, это передать два значения TIMESTAMP или DATETIME (или даже DATE, которые будут автоматически конвертировать MySQL), а также единица времени, в которую вы хотите разделить свою разницу.

Вы можете указать MONTH как единицу в первом параметре:

SELECT TIMESTAMPDIFF(MONTH, '2012-05-05', '2012-06-04')
-- Outputs: 0

SELECT TIMESTAMPDIFF(MONTH, '2012-05-05', '2012-06-05')
-- Outputs: 1

SELECT TIMESTAMPDIFF(MONTH, '2012-05-05', '2012-06-15')
-- Outputs: 1

SELECT TIMESTAMPDIFF(MONTH, '2012-05-05', '2012-12-16')
-- Outputs: 7

В основном это число месяцев, прошедших с первой даты в списке параметров. Это решение автоматически компенсирует различное количество дней в каждом месяце (28,30,31), а также с учетом лет високосного периода; вам не нужно беспокоиться об этом.


Месяц-разница с точностью:

Это немного сложнее, если вы хотите ввести десятичную точность в количестве прошедших месяцев, но вот как вы можете это сделать:

SELECT 
  TIMESTAMPDIFF(MONTH, startdate, enddate) +
  DATEDIFF(
    enddate,
    startdate + INTERVAL
      TIMESTAMPDIFF(MONTH, startdate, enddate)
    MONTH
  ) /
  DATEDIFF(
    startdate + INTERVAL
      TIMESTAMPDIFF(MONTH, startdate, enddate) + 1
    MONTH,
    startdate + INTERVAL
      TIMESTAMPDIFF(MONTH, startdate, enddate)
    MONTH
  )

Где startdate и enddate - ваши параметры даты, будь то из двух столбцов даты в таблице или в качестве входных параметров из script:

Примеры:

With startdate = '2012-05-05' AND enddate = '2012-05-27':
-- Outputs: 0.7097

With startdate = '2012-05-05' AND enddate = '2012-06-13':
-- Outputs: 1.2667

With startdate = '2012-02-27' AND enddate = '2012-06-02':
-- Outputs: 3.1935

Ответ 3

PERIOD_DIFF рассчитывает месяцы между двумя датами.

Например, чтобы вычислить разницу между now() и столбцом времени в вашей таблице:

select period_diff(date_format(now(), '%Y%m'), date_format(time, '%Y%m')) as months from your_table;

Ответ 4

Я также использую PERIODDIFF. Чтобы получить год и месяц даты, я использую функцию EXTRACT:

  SELECT PERIOD_DIFF(EXTRACT(YEAR_MONTH FROM NOW()), EXTRACT(YEAR_MONTH FROM time)) AS months FROM your_table;

Ответ 5

Я предпочитаю этот путь, потому что evryone ясно поймет это с первого взгляда:

SELECT
    12 * (YEAR(to) - YEAR(from)) + (MONTH(to) - MONTH(from)) AS months
FROM
    tab;

Ответ 6

В руководстве по MySQL:

PERIOD_DIFF (Р1, Р2)

Возвращает количество месяцев между периодами P1 и P2. P1 и P2 должны быть в формате YYMM или YYYYMM. Обратите внимание, что аргументы периода P1 и P2 не являются значениями даты.

mysql > SELECT PERIOD_DIFF (200802,200703);         - > 11

Таким образом, возможно сделать что-то вроде этого:

Select period_diff(concat(year(d1),if(month(d1)<10,'0',''),month(d1)), concat(year(d2),if(month(d2)<10,'0',''),month(d2))) as months from your_table;

Где d1 и d2 - выражения даты.

Мне пришлось использовать инструкции if(), чтобы убедиться, что месяцы были двузначным числом, например 02, а не 2.

Ответ 7

Есть ли лучший способ? да. Не используйте MySQL Timestamps. Помимо того, что они занимают 36 байт, с ними совсем не удобно работать. Я бы рекомендовал использовать юлианскую дату и секунды с полуночи для всех значений даты/времени. Их можно объединить, чтобы сформировать UnixDateTime. Если это хранится в DWORD (без знака 4 байтового целого), то даты до 2106 могут храниться как секунды с epoc, 01/01/1970 DWORD max val = 4 294 967 295 - DWORD может удерживать 136 лет секунд

Julian Dates очень приятно работать при расчете даты Значения UNIXDateTime подходят для работы при расчетах даты и времени Я тоже не хочу смотреть, поэтому я использую Timestamps, когда мне нужен столбец, с которым я не буду много вычислять, но я хочу, чтобы это было на первый взгляд.

Преобразование в Julian и обратно может быть сделано очень быстро на хорошем языке. С помощью указателей у меня это примерно до 900 clks (это тоже преобразование из STRING в INTEGER)

Когда вы попадаете в серьезные приложения, которые используют информацию о дате/времени, например, на финансовых рынках, даты Джулиана де-факто.

Ответ 8

Как показывают многие ответы здесь, "правильный" ответ зависит именно от того, что вам нужно. В моем случае мне нужно округлить до ближайшего целого числа.

Рассмотрим следующие примеры: 1 января → 31 января: 0 целых месяцев и почти 1 месяц. 1 января → 1 февраля? Это 1 целый месяц, а ровно 1 месяц.

Чтобы получить количество полных (полных) месяцев, используйте:

SELECT TIMESTAMPDIFF(MONTH, '2018-01-01', '2018-01-31');  => 0
SELECT TIMESTAMPDIFF(MONTH, '2018-01-01', '2018-02-01');  => 1

Чтобы получить округленную продолжительность в месяцах, вы можете использовать:

SELECT ROUND(TIMESTAMPDIFF(DAY, '2018-01-01', '2018-01-31')*12/365.24); => 1
SELECT ROUND(TIMESTAMPDIFF(DAY, '2018-01-01', '2018-01-31')*12/365.24); => 1

Это с точностью до + / - 5 дней и для диапазонов более 1000 лет. Ответ Зейна, очевидно, более точный, но он мне слишком многословен.

Ответ 9

Запрос будет выглядеть следующим образом:

select period_diff(date_format(now(),"%Y%m"),date_format(created,"%Y%m")) from customers where..

Дает несколько календарных месяцев с момента создания созданной даты в записи клиента, позволяя MySQL делать выбор месяца внутри.

Ответ 10

DROP FUNCTION IF EXISTS `calcula_edad` $$
CREATE DEFINER=`root`@`localhost` FUNCTION `calcula_edad`(pFecha1 date, pFecha2 date, pTipo char(1)) RETURNS int(11)
Begin

  Declare vMeses int;
  Declare vEdad int;

  Set vMeses = period_diff( date_format( pFecha1, '%Y%m' ), date_format( pFecha2, '%Y%m' ) ) ;

  /* Si el dia de la fecha1 es menor al dia de fecha2, restar 1 mes */
  if day(pFecha1) < day(pFecha2) then
    Set vMeses = VMeses - 1;
  end if;

  if pTipo='A' then
    Set vEdad = vMeses div 12 ;
  else
    Set vEdad = vMeses ;
  end if ;
  Return vEdad;
End

select calcula_edad(curdate(),born_date,'M') --  for number of months between 2 dates

Ответ 11

Выполните этот код и создайте функцию dateeifference, которая даст вам разницу в формате даты yyyy-mm-dd.

DELIMITER $$

CREATE FUNCTION datedifference(date1 DATE, date2 DATE) RETURNS DATE
NO SQL

BEGIN
    DECLARE dif DATE;
    IF DATEDIFF(date1, DATE(CONCAT(YEAR(date1),'-', MONTH(date1), '-', DAY(date2)))) < 0    THEN
                SET dif=DATE_FORMAT(
                                        CONCAT(
                                            PERIOD_DIFF(date_format(date1, '%y%m'),date_format(date2, '%y%m'))DIV 12 , 
                                            '-',
                                            PERIOD_DIFF(date_format(date1, '%y%m'),date_format(date2, '%y%m'))% 12 , 
                                            '-',
                                            DATEDIFF(date1, DATE(CONCAT(YEAR(date1),'-', MONTH(DATE_SUB(date1, INTERVAL 1 MONTH)), '-', DAY(date2))))),
                                        '%Y-%m-%d');
    ELSEIF DATEDIFF(date1, DATE(CONCAT(YEAR(date1),'-', MONTH(date1), '-', DAY(date2)))) < DAY(LAST_DAY(DATE_SUB(date1, INTERVAL 1 MONTH))) THEN
                SET dif=DATE_FORMAT(
                                        CONCAT(
                                            PERIOD_DIFF(date_format(date1, '%y%m'),date_format(date2, '%y%m'))DIV 12 , 
                                            '-',
                                            PERIOD_DIFF(date_format(date1, '%y%m'),date_format(date2, '%y%m'))% 12 , 
                                            '-',
                                            DATEDIFF(date1, DATE(CONCAT(YEAR(date1),'-', MONTH(date1), '-', DAY(date2))))),
                                        '%Y-%m-%d');
    ELSE
                SET dif=DATE_FORMAT(
                                        CONCAT(
                                            PERIOD_DIFF(date_format(date1, '%y%m'),date_format(date2, '%y%m'))DIV 12 , 
                                            '-',
                                            PERIOD_DIFF(date_format(date1, '%y%m'),date_format(date2, '%y%m'))% 12 , 
                                            '-',
                                            DATEDIFF(date1, DATE(CONCAT(YEAR(date1),'-', MONTH(date1), '-', DAY(date2))))),
                                        '%Y-%m-%d');
    END IF;

RETURN dif;
END $$
DELIMITER;

Ответ 12

Это зависит от того, как вы хотите определить количество месяцев. Ответьте на следующие вопросы: "Какая разница в месяцах: 15 февраля 2008 года - 12 марта 2009 года". Определяется ли это четким сокращением дней, которое зависит от високосных лет - в каком месяце это или в тот же день предыдущего месяца = 1 месяц.

Расчет для дней:

Feb 15 → 29 (високосный год) = 14 1 марта 2008 г. + 365 = 1 марта 2009 г. Мар 1 → 12 марта = 12 дней. 14 + 365 + 12 = 391 дней. Всего = 391 день/(средние дни в месяце = 30) = 13.03333

Расчет месяцев:

15 февраля 2008 - 15 февраля 2009 = 12 15 февраля → 12 марта = менее 1 месяца Всего = 12 месяцев или 13, если 15-марта 12-го месяца считается "прошедшим месяцем"

Ответ 13

SELECT * 
FROM emp_salaryrevise_view 
WHERE curr_year Between '2008' AND '2009' 
    AND MNTH Between '12' AND '1'

Ответ 14

Мне нужна разница в месяц с точностью. Хотя решение Зейна Бьена находится в правильном направлении, его второй и третий примеры дают неточные результаты. День в феврале, деленный на количество дней в феврале, не равен месяцу в мае, деленному на количество дней в мае. Поэтому второй пример должен выводить ((31-5 + 1)/31 + 13/30 =) 1.3043 и третий пример ((29-27 + 1)/29 + 2/30 + 3 =) 3.1701.

У меня появился следующий запрос:

SELECT
    '2012-02-27' AS startdate,
    '2012-06-02' AS enddate,
    TIMESTAMPDIFF(DAY, (SELECT startdate), (SELECT enddate)) AS days,
    IF(MONTH((SELECT startdate)) = MONTH((SELECT enddate)), 0, (TIMESTAMPDIFF(DAY, (SELECT startdate), LAST_DAY((SELECT startdate)) + INTERVAL 1 DAY)) / DAY(LAST_DAY((SELECT startdate)))) AS period1,     
    TIMESTAMPDIFF(MONTH, LAST_DAY((SELECT startdate)) + INTERVAL 1 DAY, LAST_DAY((SELECT enddate))) AS period2,
    IF(MONTH((SELECT startdate)) = MONTH((SELECT enddate)), (SELECT days), DAY((SELECT enddate))) / DAY(LAST_DAY((SELECT enddate))) AS period3,
    (SELECT period1) + (SELECT period2) + (SELECT period3) AS months

Ответ 15

Вы можете получить годы, месяцы и дни следующим образом:

SELECT 
username
,date_of_birth
,DATE_FORMAT(CURDATE(), '%Y') - DATE_FORMAT(date_of_birth, '%Y') - (DATE_FORMAT(CURDATE(), '00-%m-%d') < DATE_FORMAT(date_of_birth, '00-%m-%d')) AS years
,PERIOD_DIFF( DATE_FORMAT(CURDATE(), '%Y%m') , DATE_FORMAT(date_of_birth, '%Y%m') ) AS months
,DATEDIFF(CURDATE(),date_of_birth) AS days
FROM users

Ответ 16

Вы также можете попробовать следующее:

select MONTH(NOW())-MONTH(table_date) as 'Total Month Difference' from table_name;

ИЛИ

select MONTH(Newer_date)-MONTH(Older_date) as 'Total Month Difference' from table_Name;

Ответ 17

Функция PERIOD_DIFF()

Одним из способов является то, что MySQL PERIOD_DIFF() возвращает разницу между двумя периодами. Периоды должны быть в одном и том же формате, то есть ГГГГММ или ГГММ. Следует отметить, что периоды не являются значениями даты.

Код:

SELECT PERIOD_DIFF(200905,200811);

enter image description here

Ответ 18

Этот запрос работал у меня:)

SELECT * FROM tbl_purchase_receipt
WHERE purchase_date BETWEEN '2008-09-09' AND '2009-09-09'

Он просто принимает две даты и извлекает значения между ними.