2012-05-26 35 views
7

Sto cercando di ottenere la data e l'ora tra il prestito preso e la data di pagamento. Ho usato le funzioni di data e ora di PHP, ma non è sempre preciso. Come posso farlo esattamente in MySQL?Come convertire un determinato numero di giorni in anni, mesi e giorni in MySQL?

Let assumere due date, mutuo stipulato data

2009-05-24

e la data di ritorno prestito

2012-04-30

Scrivo una query MySQL

SELECT DATEDIFF('2012-04-30', '2009-05-24') `total_days`; 

restituire 1072 giorni, ovvero circa 2 anni, 11 mesi, 12 giorni.

Si prega di non rispondere con il codice PHP, già provarlo. Ecco il codice .

La funzione qui sotto usa PHP> = 5.3 Funzioni e convertire giorni per anni, mesi e giorni.

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' : '') : ''); 
} 

La funzione qui sotto usa PHP> = 5.2 Funzioni e convertire giorni per anni, mesi e giorni.

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' : '') : ''); 
} 
+3

Quanti giorni ci sono in un mese? 28? 29? 30? 31? – liquorvicar

+0

Probabilmente avrai bisogno di una stored procedure o di una funzione per farlo in MySQL. – liquorvicar

risposta

5

Il problema principale è la seguente:

  1. Al fine di calcolare la differenza tra i giorni è necessario utilizzare datediff()
  2. datediff() restituisce la differenza in giorni.
  3. Al fine di convertire giorni a una data, in modo da poter ottenere il numero di anni, ecc è necessario utilizzare from_days()
  4. from_days() non funziona in realtà prima del 1582, per citare dalla documentazione:

    "Usa FROM_DAYS() con cautela su vecchie date. non è inteso per l'uso con i valori che precedono l'avvento del calendario gregoriano (1582)"

    il minimo è di 1582, questo è stato quando l'Europa convertito da il Giuliano al calendario gregoriano.

  5. 0000-00-00 + 6 giorni è 0000-01-06, sia anteriore a 1582.

Questo significa che MySQL data funzioni sono inutili a voi.

Chiedi di farlo in MySQL "accuratamente".Dato che non puoi usare le funzioni per la data dovrai crearne di tue. Questo non sarà corretto. Quanti giorni ci sono in un anno? Non è certo sempre 365. Quanti giorni ci sono in un mese?

Consiglio vivamente di farlo in PHP.

Tuttavia, poiché sei irremovibile che non vuoi farlo, dovrai imbrogliare.

Aggiungere la data 1600-01-01 a tutto. Quindi rimuovi 1600 anni, 1 mese e 1 giorno dalla tua risposta alla fine. Uso solo questa data perché è maggiore di 1582 ed è un bel numero di round. Qualunque cosa funzionerebbe davvero, ma prima lo è, meglio è, quindi non incorrere in problemi.

Supponendo che abbiamo costruito la seguente tabella:

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') 
     ); 

La seguente query otterrà ciò che si vuole:

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 

Here's a SQL Fiddle to prove it.

Ancora una volta, questo è davvero un po 'hacky e non molto consigliato. la funzione di TIMESTAMPDIFF()

+0

È abbastanza strano che mysql non abbia niente di facile da configurare per questo problema. Spero che estenderanno presto le funzionalità :) –

+0

@Adrius, ne dubito :-). – Ben

+0

Utilizzata la versione di PHP. Nel 2014. – topher

0
SELECT DATE_FORMAT(FROM_DAYS(DATEDIFF('2012-04-30', '2009-05-24')), '%Y-%m-%d') AS `total_days` 
+1

La funzione non sembra funzionare se la differenza è inferiore a un anno o.O non ne ero a conoscenza. –

4

Uso MySQL:

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 

vedi sul sqlfiddle.

2

ho usato questo:

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 
Problemi correlati