Wednesday, March 14, 2012

PHP DateInterval gotcha!

I did some quick PHP code a little while back to produce timesheets - pretty simple: given a fixed start date in the past for fortnightly time sheets (say, perhaps,2011-10-24) figure out what date the most recent time sheet should start at. So this function ought to be able to do that, right?

# this function is subtly wrong, do not use it!
function getCurrentTimesheetStartDate($ts_start_date)
{
        $current_date = date_create("now");
        $interval_from_start = date_diff($current_date, $ts_start_date);
        $interval_from_current = ($interval_from_start->d) % 14;
        $date_interval_spec = new DateInterval("P" . $interval_from_current . "D");
        $retval = date_sub($current_date, $date_interval_spec);
        return $retval;
}

Well, not quite :-( It turns out that $interval_from_start->d fetches the number of days between the two dates within the current month (that is, if the ts_start_date is in a previous month, it will be "wrong" unless you also consider that $interval_from_start->m will be higher than zero... ). It turns out the member I need is $interval_from_start->days (the actual number of days between these two dates). Doh! So the corrected code is:

function getCurrentTimesheetStartDate($ts_start_date)
{
        $current_date = date_create("now");
        $interval_from_start = date_diff($current_date, $ts_start_date);
        $interval_from_current = ($interval_from_start->days) % 14;
        $date_interval_spec = new DateInterval("P" . $interval_from_current . "D");
        $retval = date_sub($current_date, $date_interval_spec);
        return $retval;
}

 One long-running bug successfully squashed :-)

No comments:

Post a Comment