How to calculate a date difference in calendar months?
$time_start = mktime(12,0,0,1,1,2011);
$time_end = mktime(12,0,0,7,1,2011);
$format = '%m months';
$start_date = new DateTime(date(DATE_ATOM,$time_start));
$end_date = new DateTime(date(DATE_ATOM,$time_end));
$diff = $start_date->diff($end_date, true);
echo $diff->format($format);
Outputs "5 months", I guess because it's off by an hour due to DST. However, I need to calculate the difference in calendar months; is there another class/function that will do this?
Added some fixes:
if($time_start > $time_end) list($time_start, $time_end) =开发者_如何学JAVA array($time_end, $time_start);
$time_end += (date('I',$time_end)-date('I',$time_start))*3600; // correct for DST
$start_date = new DateTime(date(DATE_ATOM,$time_start));
$end_date = new DateTime(date(DATE_ATOM,$time_end));
$start_date->modify('12pm'); // ignore time difference
$end_date->modify('12pm');
$diff = $start_date->diff($end_date);
echo $diff->format($format);
This seems to give the results I want, but I haven't fully tested it yet.
More fixes, based on Herbert's suggestions:
if($time_start > $time_end) list($time_start, $time_end) = array($time_end, $time_start);
$start_date = new DateTime();
$end_date = new DateTime();
$start_date->setTimestamp($time_start);
$end_date->setTimestamp($time_end);
$diff = $start_date->diff($end_date);
$hours = $diff->format('%h');
$mins = $diff->format('%i');
$secs = $diff->format('%s');
$start_date->setTime(12,0,0);//ignore time difference for date calculations
$end_date->setTime(12,0,0);
$diff = $start_date->diff($end_date);
$years = $diff->format('%y');
$months = $diff->format('%m');
$weeks = $diff->format('%w');
$days = $diff->format('%d');
Note that the $start_date->modify('12pm')
wasn't actually doing anything at all. Not sure why it didn't error.
Update
After messing around with a lot of different ideas it occurred to me that timestamps are in GMT (UTC). date(DATE_ATOM,$time_start)
is applying the default timezone. However, if you set the timestamp explicitly, DateTime
will assume UTC — thus, no DST problem.
The following code seems to work regardless of timezone or DST.
<?php
$time_start = mktime(12,0,0,1,1,2011);
$time_end = mktime(12,0,0,7,1,2011)
$start_date = new DateTime();
$end_date = new DateTime();
$start_date->setTimestamp($time_start);
$end_date->setTimestamp($time_end);
$diff = $start_date->diff($end_date);
$format = '%m months';
echo $diff->format($format);
?>
I tested some edge cases — both date and time, and a variety of timezones — but I haven’t tested every possibility so if you come across an issue, I’d be interested in hearing about it.
精彩评论