Php datetime diff months

date_diff

Returns the difference between two DateTimeInterface objects.

Parameters

Should the interval be forced to be positive?

Return Values

The DateInterval object represents the difference between the two dates.

The return value more specifically represents the clock-time interval to apply to the original object ( $this or $originObject ) to arrive at the $targetObject . This process is not always reversible.

The method is aware of DST changeovers, and hence can return an interval of 24 hours and 30 minutes , as per one of the examples. If you want to calculate with absolute time, you need to convert both the $this / $baseObject , and $targetObject to UTC first.

Examples

Example #1 DateTimeImmutable::diff() example

$origin = new DateTimeImmutable ( ‘2009-10-11’ );
$target = new DateTimeImmutable ( ‘2009-10-13’ );
$interval = $origin -> diff ( $target );
echo $interval -> format ( ‘%R%a days’ );
?>

$origin = date_create ( ‘2009-10-11’ );
$target = date_create ( ‘2009-10-13’ );
$interval = date_diff ( $origin , $target );
echo $interval -> format ( ‘%R%a days’ );
?>

The above examples will output:

Example #2 DateTimeInterface::diff() during DST changeover

$originalTime = new DateTimeImmutable ( «2021-10-30 09:00:00 Europe/London» );
$targedTime = new DateTimeImmutable ( «2021-10-31 08:30:00 Europe/London» );
$interval = $originalTime -> diff ( $targedTime );
echo $interval -> format ( «%H:%I:%S (Full days: %a)» ), «\n» ;
?>

The above example will output:

Example #3 DateTime object comparison

$date1 = new DateTime ( «now» );
$date2 = new DateTime ( «tomorrow» );

var_dump ( $date1 == $date2 );
var_dump ( $date1 < $date2 );
var_dump ( $date1 > $date2 );
?>

The above example will output:

bool(false) bool(true) bool(false)

See Also

  • DateInterval::format() — Formats the interval
  • DateTime::add() — Modifies a DateTime object, with added amount of days, months, years, hours, minutes and seconds
  • DateTime::sub() — Subtracts an amount of days, months, years, hours, minutes and seconds from a DateTime object

User Contributed Notes

Источник

date_diff

Returns the difference between two DateTimeInterface objects.

Parameters

Should the interval be forced to be positive?

Return Values

The DateInterval object represents the difference between the two dates or false on failure.

The return value more specifically represents the interval to apply to the original object ( $this or $originObject ) to arrive at the $targetObject . This process is not always reversible.

Examples

Example #1 DateTime::diff() example

$origin = new DateTime ( ‘2009-10-11’ );
$target = new DateTime ( ‘2009-10-13’ );
$interval = $origin -> diff ( $target );
echo $interval -> format ( ‘%R%a days’ );
?>

$origin = date_create ( ‘2009-10-11’ );
$target = date_create ( ‘2009-10-13’ );
$interval = date_diff ( $origin , $target );
echo $interval -> format ( ‘%R%a days’ );
?>

The above examples will output:

Example #2 DateTime object comparison

Note:

DateTime objects can be compared using comparison operators.

$date1 = new DateTime ( «now» );
$date2 = new DateTime ( «tomorrow» );

var_dump ( $date1 == $date2 );
var_dump ( $date1 < $date2 );
var_dump ( $date1 > $date2 );
?>

The above example will output:

bool(false) bool(true) bool(false)

See Also

  • DateInterval::format() — Formats the interval
  • DateTime::add() — Adds an amount of days, months, years, hours, minutes and seconds to a DateTime object
  • DateTime::sub() — Subtracts an amount of days, months, years, hours, minutes and seconds from a DateTime object
Читайте также:  Index php id 101

User Contributed Notes 31 notes

It is worth noting, IMO, and it is implied in the docs but not explicitly stated, that the object on which diff is called is subtracted from the object that is passed to diff.

i.e. $now->diff($tomorrow) is positive.

There is an interesting quirk around leap days. If the first date is a leap date (29th February in a leap year) and the second date is not a leap year, the results may not be what you expect:

$tz = new DateTimeZone ( ‘UTC’ );
$dt1 = new DateTime ( ‘2012-02-29 13:00:00’ , $tz );
$dt2 = new DateTime ( ‘2013-03-01 12:00:00’ , $tz );
print $dt1 -> diff ( $dt2 )-> format ( ‘%r%y years, %m months, %d days, %h hours, %i minutes, %s seconds’ );

/* Output:
0 years, 11 months, 30 days, 23 hours, 0 minutes, 0 seconds
*/
?>

If you reverse the order of the dates you get:

print $dt2 -> diff ( $dt1 )-> format ( ‘%r%y years, %m months, %d days, %h hours, %i minutes, %s seconds’ );

/* Output:
-1 years, 0 months, 0 days, 23 hours, 0 minutes, 0 seconds
*/
?>

$date1 = new DateTime(‘now’);
$date2 = new DateTime(‘tomorrow’);

$interval = date_diff($date1, $date2);

echo $interval->format(‘In %a days’);

In some situations, this won’t say «in 1 days», but «in 0 days».
I think this is because «now» is the current time, while «tomorrow» is the current day +1 but at a default time, lets say:

Now: 08:00pm, 01.01.2015
Tomorrow: 00:00am, 02.01.2015

In this case, the difference is not 24 hour, so it will says 0 days.

Better use «today», which should also use a default value like:

Today: 00:00am, 01.01.2015
Tomorrow: 00:00am, 02.01.2015

which now is 24 hour and represents 1 day.

This may sound logical and many will say «of course, this is right», but if you use it in a naiv way (like I did without thinking), you can come to this moment and facepalm yourself.

Conclusion: «Now» is «Today», but in a different clock time, but still the same day!

After wrestling with DateTime::diff for a while it finally dawned on me the problem was both in the formatting of the input string and the formatting of the output.

The task was to calculate the duration between two date/times.

1. Make sure you have a valid date variable. Both of these strings are valid:

$strStart = ‘2013-06-19 18:25’ ;
$strEnd = ’06/19/13 21:47′ ;

?>

2. Next convert the string to a date variable
~~~

$dteStart = new DateTime ( $strStart );
$dteEnd = new DateTime ( $strEnd );

3. Calculate the difference
~~~

$dteDiff = $dteStart -> diff ( $dteEnd );

print $dteDiff -> format ( «%H:%I:%S» );

[Modified by moderator for clarify]

Using the identical (===) comparision operator in different but equal objects will return false

$c = new DateTime ( ‘2014-04-20’ );
$d = new DateTime ( ‘2014-04-20’ );
var_dump ( $d === $d ); #true
var_dump ( $d === $c ); #false
var_dump ( $d == $c ); #true
?>

Читайте также:  Firefox version in javascript

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’.

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 ;
>
?>

It seems that while DateTime in general does preserve microseconds, DateTime::diff doesn’t appear to account for it when comparing.

$val1 = ‘2014-03-18 10:34:09.939’ ;
$val2 = ‘2014-03-18 10:34:09.940’ ;

$datetime1 = new DateTime ( $val1 );
$datetime2 = new DateTime ( $val2 );
echo «» ;
var_dump ( $datetime1 -> diff ( $datetime2 ));

if( $datetime1 > $datetime2 )
echo «1 is bigger» ;
else
echo «2 is bigger» ;
?>

The var_dump shows that there is no «u» element, and «2 is bigger» is echoed.

To work around this apparent limitation/oversight, you have to additionally compare using DateTime::format.

if( $datetime1 > $datetime2 )
echo «1 is bigger» ;
else if ( $datetime1 -> format ( ‘u’ ) > $datetime2 -> format ( ‘u’ ))
echo «1 is bigger» ;
else
echo «2 is bigger» ;
?>

I needed to get the exact number of days between 2 dates and was relying on the this diff function, but found that I was getting a peculiar result with:

$today = new DateTime ( date ( ‘2011-11-09’ ));
$appt = new DateTime ( date ( ‘2011-12-09’ ));
$days_until_appt = $appt -> diff ( $today )-> d ;
?>

This was returning 0 because it was exactly one month.

$days_until_appt = $appt -> diff ( $today )-> days ;
?>

to get 30.

Be careful, the behaviour depends on the time zones in a weird way.

function printDiff ( $tz ) $d1 = new DateTime ( «2015-06-01» , new DateTimeZone ( $tz ));
$d2 = new DateTime ( «2015-07-01» , new DateTimeZone ( $tz ));
$diff = $d1 -> diff ( $d2 );
print( $diff -> format ( «Year: %Y Month: %M Day: %D» ). PHP_EOL );
>
printDiff ( «UTC» );
printDiff ( «Australia/Melbourne» );
?>

The result is different:

Year: 00 Month: 01 Day: 00
Year: 00 Month: 00 Day: 30

Though I found a number of people who ran into the issue of 5.2 and lower not supporting this function, I was unable to find any solid examples to get around it. Therefore I hope this can help some others:

function get_timespan_string ( $older , $newer ) <
$Y1 = $older -> format ( ‘Y’ );
$Y2 = $newer -> format ( ‘Y’ );
$Y = $Y2 — $Y1 ;

$m1 = $older -> format ( ‘m’ );
$m2 = $newer -> format ( ‘m’ );
$m = $m2 — $m1 ;

Читайте также:  Python online compiler trinket

$d1 = $older -> format ( ‘d’ );
$d2 = $newer -> format ( ‘d’ );
$d = $d2 — $d1 ;

$H1 = $older -> format ( ‘H’ );
$H2 = $newer -> format ( ‘H’ );
$H = $H2 — $H1 ;

$i1 = $older -> format ( ‘i’ );
$i2 = $newer -> format ( ‘i’ );
$i = $i2 — $i1 ;

$s1 = $older -> format ( ‘s’ );
$s2 = $newer -> format ( ‘s’ );
$s = $s2 — $s1 ;

if( $s < 0 ) <
$i = $i — 1 ;
$s = $s + 60 ;
>
if( $i < 0 ) <
$H = $H — 1 ;
$i = $i + 60 ;
>
if( $H < 0 ) <
$d = $d — 1 ;
$H = $H + 24 ;
>
if( $d < 0 ) <
$m = $m — 1 ;
$d = $d + get_days_for_previous_month ( $m2 , $Y2 );
>
if( $m < 0 ) <
$Y = $Y — 1 ;
$m = $m + 12 ;
>
$timespan_string = create_timespan_string ( $Y , $m , $d , $H , $i , $s );
return $timespan_string ;
>

function get_days_for_previous_month ( $current_month , $current_year ) <
$previous_month = $current_month — 1 ;
if( $current_month == 1 ) <
$current_year = $current_year — 1 ; //going from January to previous December
$previous_month = 12 ;
>
if( $previous_month == 11 || $previous_month == 9 || $previous_month == 6 || $previous_month == 4 ) <
return 30 ;
>
else if( $previous_month == 2 ) <
if(( $current_year % 4 ) == 0 ) < //remainder 0 for leap years
return 29 ;
>
else <
return 28 ;
>
>
else <
return 31 ;
>
>

function create_timespan_string ( $Y , $m , $d , $H , $i , $s )
<
$timespan_string = » ;
$found_first_diff = false ;
if( $Y >= 1 ) <
$found_first_diff = true ;
$timespan_string .= pluralize ( $Y , ‘year’ ). ‘ ‘ ;
>
if( $m >= 1 || $found_first_diff ) <
$found_first_diff = true ;
$timespan_string .= pluralize ( $m , ‘month’ ). ‘ ‘ ;
>
if( $d >= 1 || $found_first_diff ) <
$found_first_diff = true ;
$timespan_string .= pluralize ( $d , ‘day’ ). ‘ ‘ ;
>
if( $H >= 1 || $found_first_diff ) <
$found_first_diff = true ;
$timespan_string .= pluralize ( $H , ‘hour’ ). ‘ ‘ ;
>
if( $i >= 1 || $found_first_diff ) <
$found_first_diff = true ;
$timespan_string .= pluralize ( $i , ‘minute’ ). ‘ ‘ ;
>
if( $found_first_diff ) <
$timespan_string .= ‘and ‘ ;
>
$timespan_string .= pluralize ( $s , ‘second’ );
return $timespan_string ;
>

function pluralize ( $count , $text )
<
return $count . ( ( $count == 1 ) ? ( » $text » ) : ( » $ < text >s» ) );
>
?>

Источник

date_diff

Возвращает разницу между двумя DateTimeInterface объектами.

Список параметров

Дата и время для сравнения.

Используется, чтобы вернуть абсолютную разницу.

Возвращаемые значения

DateInterval объект представляет разницу между двумя датами или FALSE в случае возникновения ошибки.

Примеры

Пример #1 Пример использования DateTime::diff()

$datetime1 = new DateTime ( ‘2009-10-11’ );
$datetime2 = new DateTime ( ‘2009-10-13’ );
$interval = $datetime1 -> diff ( $datetime2 );
echo $interval -> format ( ‘%R%a дней’ );
?>

$datetime1 = date_create ( ‘2009-10-11’ );
$datetime2 = date_create ( ‘2009-10-13’ );
$interval = date_diff ( $datetime1 , $datetime2 );
echo $interval -> format ( ‘%R%a дней’ );
?>

Результат выполнения данных примеров:

Пример #2 Сравнение объектов DateTime

Замечание:

В PHP 5.2.2 объекты DateTime сравнивались при помощи операторов сравнения.

$date1 = new DateTime ( «now» );
$date2 = new DateTime ( «tomorrow» );

var_dump ( $date1 == $date2 );
var_dump ( $date1 < $date2 );
var_dump ( $date1 > $date2 );
?>

Результат выполнения данного примера:

bool(false) bool(true) bool(false)

Смотрите также

  • DateInterval::format() — Форматирует интервал
  • DateTime::add() — Добавляет заданное количество дней, месяцев, лет, часов, минут и секунд к объекту DateTime
  • DateTime::sub() — Вычитает заданное количество дней, месяцев, лет, часов, минут и секунд из времени объекта DateTime

Источник

Оцените статью