2010-04-21 14 views
10

C'è un modo per trovare la differenza mensile in PHP? Ho l'input di dal 2003-10-17 e fino al 2004-03-24. Devo trovare quanti mesi ci sono in questi due giorni. Dire se 6 mesi, ho bisogno dell'output solo in mesi. Grazie per avermi guidato per la differenza di giorno.Trova la differenza di mese in php?

Trovo la soluzione tramite MySQL ma ne ho bisogno in PHP. Qualcuno mi aiuti, grazie in anticipo.

+2

Che cosa è esattamente un mese in questo caso? Il mese di calendario? 30 giorni? –

+3

Duplicati: http://stackoverflow.com/search?q=date+difference+php – Gordon

risposta

-2

Ecco una veloce:

$date1 = mktime(0,0,0,10,0,2003); // m d y, use 0 for day 
$date2 = mktime(0,0,0,3,0,2004); // m d y, use 0 for day 

echo round(($date2-$date1)/60/60/24/30); 
+21

Questo diventerà sempre più impreciso più a parte le due date sono e potrebbero eventualmente arrotondare nel modo sbagliato ... – deceze

+7

Cosa succederà se il mese ha "31 giorni" nel caso in cui "gennaio, marzo, maggio, luglio, agosto, ottobre, dicembre" o "28 giorni" nel caso "febbraio", coz diviso per 30. – Frank

0
<?php 
    # end date is 2008 Oct. 11 00:00:00 
    $_endDate = mktime(0,0,0,11,10,2008); 
    # begin date is 2007 May 31 13:26:26 
    $_beginDate = mktime(13,26,26,05,31,2007); 

    $timestamp_diff= $_endDate-$_beginDate +1 ; 
    # how many days between those two date 
    $days_diff = $timestamp_diff/2635200; 

?> 

Riferimento: http://au.php.net/manual/en/function.mktime.php#86916

+4

Lo stesso problema della soluzione di @ Kai, molto ottimista supposizione che un mese abbia 30 giorni ... – deceze

60

Il modo più semplice, senza reinventare la ruota. Questo ti darà la differenza completa mesi. Cioè le due date seguenti sono quasi a 76 mesi di distanza, ma il risultato è di 75 mesi.

date_default_timezone_set('Asia/Tokyo'); // you are required to set a timezone 

$date1 = new DateTime('2009-08-12'); 
$date2 = new DateTime('2003-04-14'); 

$diff = $date1->diff($date2); 

echo (($diff->format('%y') * 12) + $diff->format('%m')) . " full months difference"; 
+0

ottimo lavoro: solo una piccola domanda in questo come ottenere il numero di giorni usando questo? –

+2

@noobie Perfavore [RTFM per 'DateInterval :: format'] (http://php.net/manual/en/dateinterval.format.php) per trovare tutte le possibili opzioni di formattazione. – deceze

+1

Risultati strani: Dal: 2013-03-01, fino al: 2013-04-01, anno diff: 0, diff mese: 1, diff giorni: 3. I mesi con meno di 31 giorni danno anche differ in mesi = 0 – thehpi

0
function monthsDif($start, $end) 
{ 
    // Assume YYYY-mm-dd - as is common MYSQL format 
    $splitStart = explode('-', $start); 
    $splitEnd = explode('-', $end); 

    if (is_array($splitStart) && is_array($splitEnd)) { 
     $startYear = $splitStart[0]; 
     $startMonth = $splitStart[1]; 
     $endYear = $splitEnd[0]; 
     $endMonth = $splitEnd[1]; 

     $difYears = $endYear - $startYear; 
     $difMonth = $endMonth - $startMonth; 

     if (0 == $difYears && 0 == $difMonth) { // month and year are same 
      return 0; 
     } 
     else if (0 == $difYears && $difMonth > 0) { // same year, dif months 
      return $difMonth; 
     } 
     else if (1 == $difYears) { 
      $startToEnd = 13 - $startMonth; // months remaining in start year(13 to include final month 
      return ($startToEnd + $endMonth); // above + end month date 
     } 
     else if ($difYears > 1) { 
      $startToEnd = 13 - $startMonth; // months remaining in start year 
      $yearsRemaing = $difYears - 2; // minus the years of the start and the end year 
      $remainingMonths = 12 * $yearsRemaing; // tally up remaining months 
      $totalMonths = $startToEnd + $remainingMonths + $endMonth; // Monthsleft + full years in between + months of last year 
      return $totalMonths; 
     } 
    } 
    else { 
     return false; 
    } 
} 
+1

Ammended - changed $ startToEnd = 12 - $ startMonth; a $ startToEnd = 13 - $ startMonth; Come prima non stava contando la durata di dicembre –

6

Wow, modo di pensare troppo il problema ... Che ne dite di questa versione:

function monthsBetween($startDate, $endDate) { 
    $retval = ""; 

    // Assume YYYY-mm-dd - as is common MYSQL format 
    $splitStart = explode('-', $startDate); 
    $splitEnd = explode('-', $endDate); 

    if (is_array($splitStart) && is_array($splitEnd)) { 
     $difYears = $splitEnd[0] - $splitStart[0]; 
     $difMonths = $splitEnd[1] - $splitStart[1]; 
     $difDays = $splitEnd[2] - $splitStart[2]; 

     $retval = ($difDays > 0) ? $difMonths : $difMonths - 1; 
     $retval += $difYears * 12; 
    } 
    return $retval; 
} 

NB: a differenza di molte delle altre soluzioni, questo non dipende dalle funzioni di data aggiunto in PHP 5.3, dato che molti host condivisi non ci sono ancora.

+0

ho appena modificato questa riga '' '$ retval = ($ difDays> 0)? $ difMonths: $ difMonths - 1; '' 'a' '' $ retval = ($ difDays> = 0)? $ difMonths: $ difMonths - 1; '' 'Quindi la differenza tra 2017-02-01 e 2017-03-01 è solo 1 – jona303

14

Dopo il test t di soluzioni, mettendo il tutto in un test di unità, questo è quello esco con:

/** 
* Calculate the difference in months between two dates (v1/18.11.2013) 
* 
* @param \DateTime $date1 
* @param \DateTime $date2 
* @return int 
*/ 
public static function diffInMonths(\DateTime $date1, \DateTime $date2) 
{ 
    $diff = $date1->diff($date2); 

    $months = $diff->y * 12 + $diff->m + $diff->d/30; 

    return (int) round($months); 
} 

Per esempio restituisca (casi di test dal test di unità):

  • 2013/01/11 - 30.11.2013 - 1 settimana
  • 01.01.2013 - 31.12.2013 - 12 mesi
  • 31.01.2011 - 28.02.2011 - 1 settimana
  • 01.09.2009 - 01.05.2010 - 8 mesi
  • 01.01.2013 - 31.03.2013 - 3 mesi
  • 15.02.2013 - 15.04.2013 - 2 mesi
  • 1985/02/01 - 31.12.2013 - 347 mesi

Avviso: A causa dell'arrotondamento con i giorni, anche la metà di un mese verrà arrotondata, il che potrebbe causare problemi se lo si utilizza in alcuni casi. Quindi NON UTILIZZARLO per questi casi, ti causerà problemi.

Ad esempio:

  • 02.11.2013 - 31.12.2013 tornerà 2, non è 1 (come previsto).
+0

bella soluzione, ad esempio 01.06 - 01.07 fornisce 0 mesi (in m), ma utilizzando giorni e arrotondamento funziona correttamente – Eddie

5

Volevo solo aggiungere questo se qualcuno è alla ricerca di una soluzione semplice che conta ogni mese toccato al posto di mesi completi, arrotondati mesi o qualcosa del genere.

// Build example data 
$timeStart = strtotime("2003-10-17"); 
$timeEnd = strtotime("2004-03-24"); 
// Adding current month + all months in each passed year 
$numMonths = 1 + (date("Y",$timeEnd)-date("Y",$timeStart))*12; 
// Add/subtract month difference 
$numMonths += date("m",$timeEnd)-date("m",$timeStart); 

echo $numMonths; 
0
// get year and month difference 

$a1 = '20170401'; 

$a2 = '20160101' 

$yearDiff = (substr($a1, 0, 4) - substr($a2, 0, 4)); 

$monthDiff = (substr($a1, 4, 2) - substr($a2, 4, 2)); 

$fullMonthDiff = ($yearDiff * 12) + $monthDiff; 

// fullMonthDiff = 16 
0

Questa è la mia versione migliorata del @deceze risposta:

/** 
* @param string $startDate 
* Current date is considered if empty string is passed 
* @param string $endDate 
* Current date is considered if empty string is passed 
* @param bool $unsigned 
* If $unsigned is true, difference is always positive, otherwise the difference might be negative 
* @return int 
*/ 
public static function diffInFullMonths($startDate, $endDate, $unsigned = false) 
{ 
    $diff = (new DateTime($startDate))->diff(new DateTime($endDate)); 
    $reverse = $unsigned === true ? '' : '%r'; 
    return ((int) $diff->format("{$reverse}%y") * 12) + ((int) $diff->format("{$reverse}%m")); 
} 
0

Il modo migliore.

function getIntervals(DateTime $from, DateTime $to) 
{ 
    $intervals = []; 
    $startDate = $from->modify('first day of this month'); 
    $endDate = $to->modify('last day of this month'); 
    while($startDate < $endDate){ 
     $firstDay = $startDate->format('Y-m-d H:i:s'); 
     $startDate->modify('last day of this month')->modify('+1 day'); 
     $intervals[] = [ 
      'firstDay' => $firstDay, 
      'lastDay' => $startDate->modify('-1 second')->format('Y-m-d H:i:s'), 
     ]; 
     $startDate->modify('+1 second'); 
    } 
    return $intervals; 
} 
$dateTimeFirst = new \DateTime('2013-01-01'); 
$dateTimeSecond = new \DateTime('2013-03-31'); 
$interval = getIntervals($dateTimeFirst, $dateTimeSecond); 
print_r($interval); 

Risultato:

Array 
(
    [0] => Array 
     (
      [firstDay] => 2013-01-01 00:00:00 
      [lastDay] => 2013-01-31 23:59:59 
     ) 

    [1] => Array 
     (
      [firstDay] => 2013-02-01 00:00:00 
      [lastDay] => 2013-02-28 23:59:59 
     ) 

    [2] => Array 
     (
      [firstDay] => 2013-03-01 00:00:00 
      [lastDay] => 2013-03-31 23:59:59 
     ) 

) 
0

Nel mio caso avevo bisogno di contare mesi e gli avanzi di giorno pieno come mese e per costruire un grafico a linee etichette.

/** 
* Calculate the difference in months between two dates 
* 
* @param \DateTime $from 
* @param \DateTime $to 
* @return int 
*/ 
public static function diffInMonths(\DateTime $from, \DateTime $to) 
{ 
    // Count months from year and month diff 
    $diff = $to->diff($from)->format('%y') * 12 + $to->diff($from)->format('%m'); 

    // If there is some day leftover, count it as the full month 
    if ($to->diff($from)->format('%d') > 0) $diff++; 

    // The month count isn't still right in some cases. This covers it. 
    if ($from->format('d') >= $to->format('d')) $diff++; 
} 
1
$datetime1 = date_create('2009-10-11'); 

$datetime2 = date_create('2013-1-13'); 

$interval = date_diff($datetime1, $datetime2); 

echo $interval->format('%a day %m month %y year'); 
+0

Giorno Mese Anno Differenza in php –

Problemi correlati