I had an issue recently where I needed to calculate the Unix timestamp for the daylight savings time boundaries. According to the United States Naval Observatory, daylight savings time begins the Second Sunday of March and ends on the First Sunday of November.
Awkward date calculations if you don’t have the magical strtotime() function in PHP. strtotime() is able to do relativistic time conversions from the common “+1 hours” to the more complex (and more relevant) “Second Sunday March 0″.
Why do we do the ‘March 0′ in the above string to calculate the start boundary? Doing some tests with strtotime() reveals some behavior you should be aware of.
strtotime("March"); doesn’t actually give you the first of March, it gives you the current day in the month specified (date('D, F j, Y, g:i a', strtotime("March")); returns Tue, March 10, 2009, 12:00 am at the time of this post). Doing a similar test but substituting April for March results in the 10th of April (at 12 am).
Now in most cases doing a strtotime("March 1") will suffice (date('D, F j, Y, g:i a', strtotime("March 1")); results in Sun, March 1, 2009, 12:00 am). However, as you can tell, this month is going to be awkward because the first day of the month is a Sunday. strtotime(), when calculating the fuzzy “Second Sunday,” doesn’t include the current day. So calculating date('D, F j, Y, g:i a', strtotime("Second Sunday March 1")); will actually return the 3rd Sunday (Sun, March 15, 2009, 12:00 am).
So our solution is actually to take a step back and return the PREVIOUS day to the first day of March and then calculate the Second Sunday from there (since we know that starting from the next day will account for the first). Normally, dealing with the last day in February is a headache, BUT again thanks to PHP magic we don’t have to figure out if it’s February 28th or 29th, we merely do a “March 0″ which steps us back a month (date('D, F j, Y, g:i a', strtotime("March 0")); returns Sat, February 28, 2009, 12:00 am). From there we can calculate the Second Sunday with ease and eventually determine that the second sunday is March 8th, which is confirmed by the above USNO website.
Applying these lessons to calculating the first Sunday in November we come up with the following snippit:
<?php
$remove_hour = strtotime("Second Sunday March 0");
$add_hour = strtotime("First Sunday November 0");
$time = time();
if( $time >= $remove_hour && $time < $add_hour )
{
var_dump("Lost an hour");
}
else
{
var_dump("Gained an hour");
}
Cheers!
Comments 5
Well, what is the purpose of having those boundaries as timestamps? If you set the timezone, php date functions will calculate the hour shift accordingly. However,
Posted 10 Mar 2009 at 11:06 am ¶date(‘I’, $time)
will tell you if dst is on at that time.
The system I was working on was importing the timestamps and the DST information wasn’t being applied correctly.
My solution may be a temporary hack but it was a fun exercise playing with strtotime() and realizing how good I have it with PHP’s date functions.
Posted 10 Mar 2009 at 11:14 am ¶Does your code work for non-USA timezones like in the UK?
Posted 25 Apr 2009 at 9:25 pm ¶Thanks for this script. The php docs just weren’t clear enough for me, plus Yahoo! hasn’t upgraded to php 5 yet, so this is an awesome hack around.
Posted 11 Sep 2009 at 6:50 am ¶nice post, it helped me a lot
Posted 01 Sep 2010 at 11:50 pm ¶Trackbacks & Pingbacks 1
[...] Cousineau has written up some timely advice in a new post to his blog. It looks at pinpointing the time boundary for Daylight Savings Time in a PHP script [...]
Post a Comment