Question

Je cherche à calculer le nombre de mois entre 2 champs de date et heure.

Existe-t-il un meilleur moyen que d'obtenir l'horodatage Unix, de diviser par 2 592 000 secondes et d'arrondir dans MySQL?

Était-ce utile?

La solution

Le DATEDIFF fonction peut vous donner le nombre de jours entre deux dates. Qu'est-ce qui est plus précis, puisque ... comment définissez-vous un mois? (28, 29, 30 ou 31 jours?)

Autres conseils

Mois-différence entre deux dates données:

Je suis surpris que cela n'ait pas encore été mentionné:

Consultez le < strong> TIMESTAMPDIFF () dans MySQL.

Cela vous permet de transmettre deux valeurs TIMESTAMP ou DATETIME (ou même DATE car MySQL sera automatiquement converti) en tant que ainsi que l'unité de temps sur laquelle vous souhaitez baser votre différence.

Vous pouvez spécifier MONTH comme unité dans le premier paramètre:

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

Il obtient essentiellement le nombre de mois écoulés depuis la première date de la liste de paramètres. Cette solution compense automatiquement le nombre de jours variable chaque mois (28,30,31) et tient compte des années bissextiles - vous n’aurez plus à vous soucier de cela.

Différence mensuelle avec précision:

C’est un peu plus compliqué si vous souhaitez introduire une précision décimale dans le nombre de mois écoulés, mais voici comment vous pouvez le faire:

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 et enddate sont vos paramètres de date, qu'il s'agisse de deux colonnes de date dans une table ou de paramètres d'entrée à partir d'un script:

Exemples:

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

PERIOD_DIFF calcule les mois entre deux dates.

Par exemple, pour calculer la différence entre now () et une colonne time dans votre_table:

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

J'utilise aussi PERIODDIFF . Pour obtenir l'année et le mois de la date, j'utilise la fonction EXTRACT :

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

Je préfère cette façon, car tout le monde comprendra clairement au premier regard:

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

Comme le montrent de nombreuses réponses, la "bonne" réponse dépend exactement de ce dont vous avez besoin. Dans mon cas, je dois arrondir au nombre entier le plus proche .

Considérez ces exemples: 1er janvier - > 31 janvier: c'est 0 mois entiers et presque 1 mois. 1er janvier - > 1er février? C'est un mois entier et exactement un mois.

Pour obtenir le nombre de mois entiers (complets) , utilisez:

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

Pour obtenir une durée arrondie en mois, vous pouvez utiliser:

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

C’est précis à +/- 5 jours et pour des intervalles supérieurs à 1000 ans. La réponse de Zane est évidemment plus précise, mais elle est trop verbeuse à mon goût.

Du manuel MySQL:

  

PERIOD_DIFF (P1, P2)

     

Renvoie le nombre de mois entre les périodes P1 et P2. P1 et P2 doivent être au format AAMM ou AAAAMM. Notez que les arguments de période P1 et P2 ne sont pas des valeurs de date.

     

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

Il peut donc être possible de faire quelque chose comme ceci:

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;

Où d1 et d2 sont les expressions de date.

Je devais utiliser les instructions if () pour m'assurer que les mois étaient un nombre à deux chiffres comme 02 plutôt que 2.

Y a-t-il un meilleur moyen? Oui. N'utilisez pas les horodatages MySQL. Mis à part le fait qu'ils occupent 36 octets, ils ne sont pas du tout pratiques avec qui travailler. Je recommanderais d’utiliser Julian Date and Seconds à partir de minuit pour toutes les valeurs de date / heure. Ceux-ci peuvent être combinés pour former un UnixDateTime. Si cela est stocké dans un DWORD (entier non signé de 4 octets), les dates jusqu’à 2106 peuvent être stockées en secondes depuis epoc, 01/01/1970 DWORD max val = 4 294 967 295 - Un DWORD peut contenir 136 ans de secondes

Les dates juliennes sont très agréables à utiliser pour faire des calculs de date Les valeurs UNIXDateTime sont bonnes à utiliser pour les calculs de date / heure Il n’est pas non plus intéressant de regarder. C’est pourquoi j’utilise les horodatages lorsque j’ai besoin d’une colonne avec laquelle je ne ferai pas beaucoup de calculs, mais je veux une indication en un coup d’œil.

La conversion en julien et inversement peut être effectuée très rapidement dans un bon langage. En utilisant des pointeurs, je l’ai jusqu’à 900 Clks environ (c’est aussi une conversion de STRING en INTEGER, bien sûr)

Lorsque vous vous lancez dans des applications sérieuses qui utilisent des informations de date / heure, comme par exemple les marchés financiers, les dates en Julien sont de facto.

La requête ressemblera à:

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

Donne un nombre de mois de calendrier depuis l'enregistrement de la date de création sur un enregistrement client, laissant à MySQL le choix du mois en interne.

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

Exécutez ce code et il créera une fonction datéifference qui vous donnera la différence de format de date aaaa-mm-jj.

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;

Cela dépend de la manière dont vous souhaitez définir le nombre de mois. Répondez à ces questions: «Quelle est la différence en mois: 15 février 2008 - 12 mars 2009». Est-ce défini par un nombre de jours précis qui dépend des années bissextiles, de quel mois il s’agit ou du même jour du mois précédent = 1 mois.

Un calcul pour les jours :

15 février - > 29 (année bissextile) = 14 1 mars 2008 + 365 = 1 mars 2009. 1 mars - > 12 mars = 12 jours. 14 + 365 + 12 = 391 jours. Total = 391 jours / (jours moyens dans le mois = 30) = 13,03333

Un calcul des mois :

15 fév 2008 - 15 fév 2009 2009 = 12 15 février - > 12 mars = moins de 1 mois Total = 12 mois, ou 13 si 15 février - 12 mars est considéré comme "le mois dernier"

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

J'avais besoin de la différence de mois avec précision. Bien que la solution de Zane Bien va dans la bonne direction, ses deuxième et troisième exemples donnent des résultats inexacts. Un jour de février divisé par le nombre de jours de février n'est pas égal à un jour de mai divisé par le nombre de jours de mai. Ainsi, le deuxième exemple devrait produire ((31-5 + 1) / 31 + 13/30 =) 1,3043 et le troisième exemple ((29-27 + 1) / 29 + 2/30 + 3 =) 3.1701.

Je me suis retrouvé avec la requête suivante:

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

Vous pouvez obtenir des années, des mois et des jours de cette façon:

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

Vous pouvez également essayer ceci:

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

OU

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

Fonction PERIOD_DIFF ()

MySQL PERIOD_DIFF () renvoie la différence entre deux périodes. Les périodes doivent être au même format, c'est-à-dire AAAAMM ou AAMM. Il est à noter que les périodes ne sont pas des valeurs de date.

Code:

SELECT PERIOD_DIFF(200905,200811);

 entrer la description de l'image ici

Réponse simple en indiquant la date de début comme ins_frm et la date de fin en tant que ins_to

SELECT convert(TIMESTAMPDIFF(year, ins_frm, ins_to),UNSIGNED) as yrs,
       mod(TIMESTAMPDIFF(MONTH, ins_frm, ins_to),12) mnths
FROM table_name

Enjoy:)))

Essayez ceci

SELECT YEAR(end_date)*12 + MONTH(end_date) - (YEAR(start_date)*12 + MONTH(start_date))

Cette requête a fonctionné pour moi:)

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

Il suffit de prendre deux dates et de récupérer les valeurs entre elles.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top