I was looking for a way to output X number of days from a given date and didn't find exactly what I was looking for. But I got this working. I hope this helps you.
This will output the number of days,months, or years difference between NOW and a April 1st, 2011.
<?php
$date1 = new DateTime('2011-04-01');
$date2 = new DateTime("now");
$interval = $date1->diff($date2);
$years = $interval->format('%y');
$months = $interval->format('%m');
$days = $interval->format('%d');
if($years!=0){
$ago = $years.' year(s) ago';
}else{
$ago = ($months == 0 ? $days.' day(s) ago' : $months.' month(s) ago');
}
echo $ago;
?>
If I used today, 2011-05-16 as $date1, I could return all 0's in the format. For example....
<?php
$date1 = new DateTime('2011-05-161');
$date2 = new DateTime("now");
$interval = $date1->diff($date2);
$diff = $interval->format('%y-%m-%d');
echo $diff; //Today, this will output 0-0-0
?>
DateTime::diff
(PHP 5 >= 5.3.0)
DateTime::diff — Devuelve la diferencia entres objetos DateTime
Descripción
Estilo orientado a objetos
Estilo por procesos
Devuelve la diferencia entres objetos DateTime.
Parámetros
- datetime
-
La fecha a comparar.
- absolute
-
Si se devulve la diferencia absoluta.
Valores devueltos
El objeto DateInterval que representa la diferencia entre dos fechas o FALSE en caso de error.
Ejemplos
Example #1 Ejemplo de DateTime::diff()
Estilo orientado a objetos
<?php
$datetime1 = new DateTime('2009-10-11');
$datetime2 = new DateTime('2009-10-13');
$intervalo = $datetime1->diff($datetime2);
echo $intervalo->format('%R%a días');
?>
Estilo por procesos
<?php
$datetime1 = date_create('2009-10-11');
$datetime2 = date_create('2009-10-13');
$intervalo = date_diff($datetime1, $datetime2);
echo $intervalo->format('%R%a días');
?>
El resultado de los ejemplos serían:
+2 días
Example #2 Comparación de objetos DateTime
Note:
A partir de PHP 5.2.2, los objetos DateTime se pueden comparar utilizando operadores de comparación.
<?php
$date1 = new DateTime("now");
$date2 = new DateTime("tomorrow");
var_dump($date1 == $date2);
var_dump($date1 < $date2);
var_dump($date1 > $date2);
?>
El resultado del ejemplo sería:
bool(false) bool(true) bool(false)
Ver también
- DateInterval::format() - Formatea el intervalo
- DateTime::add() - Añade una cantidad de días, meses, años, horas, minutos y segundos al objeto DateTime
- DateTime::sub() - Sustrae una cantidad de días, meses, años, horas, minutos y segundos de un objeto DateTime
milespickens+php at gmail dot com
16-May-2011 10:00
Grgoire Marchal
18-Feb-2011 10:22
Warning, there's a bug on windows platforms: the result is always 6015 days (and not 42...)
http://bugs.php.net/bug.php?id=51184
schindhelm at gmail dot com
21-Jan-2011 08:48
I found that DateTime::diff isn't as accurate as I thought. I calculated the age gap between now and a birthdate from before 1970 (unix epoch). Here's what I got:
Given today is January 21st, 2011:
<?php
date_default_timezone_set('Europe/Berlin');
// birthdate format is YYYY-MM-DD
$birth = new DateTime('1966-01-21');
$today = new DateTime();
$diff = $birth->diff($today);
echo $diff->format('%y'); // will output 45
$birth = new DateTime('1966-01-23');
$today = new DateTime();
$diff = $birth->diff($today);
echo $diff->format('%y'); // will output 45 wrongly
$birth = new DateTime('1966-01-24'); // three days difference!
$today = new DateTime();
$diff = $birth->diff($today);
echo $diff->format('%y'); // will output 44 - correct
?>
When calculating with the date() function it was more accurate (didn't use seconds/hours for comparison).
Note that 3 days may be a lot if you want to create invoices and have to check against a given age to determine if the customer is chargable for taxes and so on.
If someone also found this behaviour I'd like to hear about it - give me a quick mail at schindhelm (at) gmail (dot) com.
Thanks.
Umair Ashraf
22-Nov-2010 07:49
for PHP version 5.3
<?php
function pluralize( $count, $text )
{
return $count . ( ( $count == 1 ) ? ( " $text" ) : ( " ${text}s" ) );
}
function ago( $datetime )
{
$interval = date_create('now')->diff( $datetime );
$suffix = ( $interval->invert ? ' ago' : '' );
if ( $v = $interval->y >= 1 ) return pluralize( $interval->y, 'year' ) . $suffix;
if ( $v = $interval->m >= 1 ) return pluralize( $interval->m, 'month' ) . $suffix;
if ( $v = $interval->d >= 1 ) return pluralize( $interval->d, 'day' ) . $suffix;
if ( $v = $interval->h >= 1 ) return pluralize( $interval->h, 'hour' ) . $suffix;
if ( $v = $interval->i >= 1 ) return pluralize( $interval->i, 'minute' ) . $suffix;
return pluralize( $interval->s, 'second' ) . $suffix;
}
?>
for PHP version 5.2
<?php
public function ago($dt)
{
$dt = date_parse($dt);
$now = date_parse(date("Y-m-d H:i:s"));
$suffix = " ago";
if ($now['year'] != $dt['year']) return $this->pluralize($now['year'] - $dt['year'], "year") . $suffix;
if ($now['month'] != $dt['month']) return $this->pluralize($now['month'] - $dt['month'], "month") . $suffix;
if ($now['day'] != $dt['day']) return $this->pluralize($now['day'] - $dt['day'], "day") . $suffix;
if ($now['hour'] != $dt['hour']) return $this->pluralize($now['hour'] - $dt['hour'], "hour") . $suffix;
if ($now['minute'] != $dt['minute']) return $this->pluralize($now['minute'] - $dt['minute'], "minute") . $suffix;
if ($now['second'] != $dt['second']) return $this->pluralize($now['second'] - $dt['second'], "second") . $suffix;
return "just now";
}
private function pluralize($count, $text)
{
return $count . (($count == 1) ? (" $text") : (" ${text}s"));
}
?>
acrion at gmail dot com
13-May-2010 03:52
If you want to quickly scan through the resulting intervals, you can use the undocumented properties of DateInterval.
The function below returns a single number of years, months, days, hours, minutes or seconds between the current date and the provided date. If the date occurs in the past (is negative/inverted), it suffixes it with 'ago'.
<?php
function pluralize( $count, $text )
{
return $count . ( ( $count == 1 ) ? ( " $text" ) : ( " ${text}s" ) );
}
function ago( $datetime )
{
$interval = date_create('now')->diff( $datetime );
$suffix = ( $interval->invert ? ' ago' : '' );
if ( $v = $interval->y >= 1 ) return pluralize( $interval->y, 'year' ) . $suffix;
if ( $v = $interval->m >= 1 ) return pluralize( $interval->m, 'month' ) . $suffix;
if ( $v = $interval->d >= 1 ) return pluralize( $interval->d, 'day' ) . $suffix;
if ( $v = $interval->h >= 1 ) return pluralize( $interval->h, 'hour' ) . $suffix;
if ( $v = $interval->i >= 1 ) return pluralize( $interval->i, 'minute' ) . $suffix;
return pluralize( $interval->s, 'second' ) . $suffix;
}
?>
Dennis C
10-May-2010 06:24
For those like me who don't yet have PHP 5.3 installed on their host, here's a simple alternative to get the number of days between two dates in the format '2010-3-23' or similar acceptable to strtotime(). You need PHP 5.2.
<?php
function date_diff($date1, $date2) {
$current = $date1;
$datetime2 = date_create($date2);
$count = 0;
while(date_create($current) < $datetime2){
$current = gmdate("Y-m-d", strtotime("+1 day", strtotime($current)));
$count++;
}
return $count;
}
echo (date_diff('2010-3-9', '2011-4-10')." days <br \>");
?>
Anonymous
04-Aug-2009 12:17
You don't need to calculate the exact difference if you just want to know what date comes earlier:
<?php
date_default_timezone_set('Europe/Madrid');
$d1 = new DateTime('1492-01-01');
$d2 = new DateTime('1492-12-31');
var_dump($d1 < $d2);
var_dump($d1 > $d2);
var_dump($d1 == $d2);
?>
bool(true)
bool(false)
bool(false)
