PHP and Dates – Tearing My Hair Out

I had an interesting problem this morning with some dates in PHP. When I use dates in PHP I generally try to handle them as a unix timestamp using the local unix time of the server. I then modify this based on clients timezone to show them their local time. This has worked fine up until now.

November the 4th 2012 was the day that daylight savings rolled back in the USA and this caused a problem when reports for one of my products were run across this transition day. The trouble was when you got a local server time and converted it to a client time. For example using something like this:

$date=mktime(8,0,0,11,4,2012); //set to 8 AM on November 4
$date_time=new DateTime("now",new DateTimeZone('America/Los_Angeles'));
$date_time->setTimestamp($date);
echo "date_time:: ".$date_time->format("D j m y h:i:s");

Resulted in a different time to:

$date=mktime(8,0,0,11,5,2012); //set to 8 AM on November 5
$date_time=new DateTime("now",new DateTimeZone('America/Los_Angeles'));
$date_time->setTimestamp($date);
echo "date_time:: ".$date_time->format("D j m y h:i:s");

Which normally isn’t a problem except when you’re cycling through a date range one day at a time by adding (24*60*60) seconds to each day and expecting the client time to be indexed one day at a time too. But, it’s not, on one of the days there’s going to be an extra hour (or an hour) less. So, the solution (and it’s horrid) is to convert server to time to local client time and add a day to that, and then convert it back to server time. Yuck. But it works, and it works something like this:

	//
	//convert to local time
	//		
	$start_date=mktime(8,0,0,11,1,2012);
	$date_time=new DateTime_52("now",new DateTimeZone('America/Los_Angeles'));
	$date_time->setTimestamp($start_date);
			
	for ($i=0;$i<7;$i++)	
	{
		$date_time->setDate($date_time->format("Y"),$date_time->format("m"),$date_time->format("j")+$i);	
		echo "day ".$i." local time ".$date_time->format("D j m y H:i:s")."<br />";
		echo "day ".$i." server time ".date("D j m y h:i:s",$date_time->getTimestamp())."<br />";
	  $first_day_of_week1=get_first_day_of_week($date_time->getTimestamp(),new DateTimeZone('America/Los_Angeles'));
		echo "day ".$i." first_day_of_week:: ".date("D j m y h:i:s",$first_day_of_week1)."<br />";
		
	}

This entry was posted in php on by .

About markn

Mark is the owner and founder of Timesheets MTS Software, an mISV that develops and markets employee timesheet and time clock software. He's also a mechanical engineer, father of four, and a lifelong lover of gadgets.