The How of When, Part 1: Making WhenIsDaylightSavingsTime.com

July 21, 2009

Some months back my good friend/collaborator (frollaborator?) Casimir Nozkowski tried to find out when the next Daylight Savings Time was. He did a web search and what he got back was a bunch of clutter. “There’s got to be a better way!”, he is rumored to have shouted.

Meanwhile, Cas knew that I was looking to create some websites that required minimal upkeep. I had told him of my plans to start building sites that were either totally automated or driven by user submissions.

And thus was born our partnership on WhenIsDaylightSavingsTime.com, his concept for a fully automated single serving site where people would find nothing but the answer to the question in the site’s name.

I want to tell you how we made WIDST because making random projects come to life is fun, rewarding and probably easier than you think.

The setup.
Cas bought the domain and I set it up on one of my existing shared web hosting accounts. Shared web hosting is CHEAP ranging from about $3-$10 per month for the ability to host unlimited domains.. Registering a domain will cost you about $10 per year.

Cas created some mockups in Photoshop of what the daily countdown should look like. When fall was the next daylight savings, the wording would say “Fall Back In…” in a harvesty orange. When spring was the DST being counted down to it would be “Spring Forward in…” in a pastoral blue.

I needed to see these mockups so that we were in agreement on site plans and to know what words were needed on the screen. But I wasn’t even going to think about how to achieve the page design yet. The first mission for me was to code the functionality of counting the days to DST so that the right text could display on the web page.

Programming
It was never a question that this site would be built in PHP. I have a lot more experience on the Microsoft side of things and have also recently become a big fan of Ruby on Rails. But PHP is the lingua franca of quick and cheap websites.

If you don’t already know, PHP (like Microsoft’s ASP) is basically a means of hooking up your otherwise dumb html pages to some kind of brain. PHP can render your html dynamically based on logic the user never sees that gets executed when the page is called for. It can change what it shows based on what the user or database has passed its way.

Remember the movie 2001? Server side programming is basically the fucking monolith for your mongoloid web page. It’s also what’s going to get you more money in the web career game. If money’s what you’re into. On those lines you’d do well to mess with the more high powered buzzwordy stuff like object-oriented php or .net but you have to start somewhere.

Lets try looking through the code for our page. I created a file called index.php (the default document when you visit the site) and it goes a little something like this.

<?php

// find our base point in time either from querystring or using the current server time

if ($_GET['time'] == "")
$time = time();
else
$time = strtotime($_GET['time']);

When a web server with php installed finds a .php file it looks for anything located in between <?php and ?> delimiters and knows to process the lines in-between differently than the dumb html it’s used to. All it has to do with html is show it, not worry about variables or conditional logic. So here we’ve started off with that <?php which says “here comes some php code for the web server to process”.

In the next line we use // to show this is a comment line to be ignored by the php processor. It’s there for the benefit of those looking at the code. As the comment explains, these first few lines are all about defining for the benefit of our code when “now” is.

We have a variable called $time that will store this value. In PHP all variables start with a $. PHP is money-obsessed like hip-hop.

So the logic of the if statement begins if ($_GET['time'] == “”). This is checking if there’s a variable called “time” in the url parameters (the name=value pairs that sometime appear after a web page address). If there is no parameter with this name, then checking the $_GET value called time will give us nothing, represented by the empty string “”.

Succinctly then, this chunk of code says if there’s no value of time in the url (if the website called is just www.whenisdaylightsavingstime.com) then set $time equal to the current time whatever that may be. Otherwise, if there is a time=some value in the url then let the time we are calling now be that time passed from the url. We put this code in here at the start to establish when now is according to the page and to allow us to override the actual current now when the page runs with a time=value passed in the url.

For example:

I didn’t know all the power of the php command strtotime (string to time) when we embarked on this project. Turns out this command is super smart about understanding the meaning of various time-related natural language strings. That allowed us different ways to test what our page will show at any given time as shown in the links above but as you’ll see it also helped us figure out exactly when the next daylight savings time was coming up without storing any dates in a database.

// find nearest daylight savings to our starting time (regardless of whether current time is before or after )
$nearest_spring_ahead = strtotime("Second Sunday March 0", $time);
$nearest_fall_back = strtotime("First Sunday November 0", $time);

The php command strtotime usually takes any string (set of text) as a parameter and returns a numeric unix timestamp if it can evaluate it as a date/time expression. But strtotime also has a second parameter for situations where the expression is relative to a given start time. This is for expressions like “+1 week” or “Next Sunday”. If only one parameter is sent to strtotime then it considers the default start-time as the current time. Here we pass the $time to override that default value. So in case we’ve set $time by putting a time parameter in the url we will now be basing our values on that.

In this chunk of code we are assigning $nearest_spring_ahead to be the closest “Second Sunday March 0″ and $nearest_fall_back to be “”First Sunday November 0″. That’s how simple it is to find a daylight savings time date thanks to the versatility of strtotime. The zeros in these expressions can be thought of as military time. Since this is a daily countdown, we’re not concerned with time and want to work with these dates from their start (12am).

Notice from the comment line and the variable name that these are the nearest spring DST and nearest fall DST as opposed to the next ones. This is just the way strtotime works, finding the closest date that matches the expression but with some further coding we can determine whatever we need to know about which DST matters for the site’s needs.

// find nearest daylight savings following our start time
if (strtotime("+1 day",$nearest_spring_ahead) > $time)
{
$next_spring = $nearest_spring_ahead;
}
else {
$next_spring = strtotime("Second Sunday March 0 +1 year", $time );
}

if (strtotime("+1 day", $nearest_fall_back) > $time) {
$next_fall = $nearest_fall_back;
}
else
{
$next_fall = strtotime("First Sunday November 0 +1 year", $time);
}

// if next upcoming dst is spring set show_spring to true otherwise false
if ($next_fall > $next_spring)
$show_spring = 1;
else
$show_spring = 0;

Here we check if our current time is more than a day past the nearest spring and fall daylight savings time, if we haven’t passed them yet then we assign $next_spring or $next_fall to have this same timestamp value. If they have already passed them then instead we assign $next_spring or $next_fall to be next year’s respective DST.

Now that we know when the next spring dst and the next fall dst are we determine which one this page should be showing with a simple greater than conditional statement. If $next_fall > $next_spring (in other words if the next fall dst is further into the future than the next spring dst) then we will show spring because it’s closer. If not, then we will show fall.

Ok, so I know today’s date (or the time I substituted for today in the url) and I know when the DST that follows that is. Now I need to count the days in between. In most languages I work with there’s some function built-in for counting the difference between two dates. But looking through the time/date functions of PHP I found no such thing.

So I did what any good programmer would do in this situation, I googled for an answer.

And I found this one with a function called count_days that did exactly what I needed. So I cut and paste and voila now I had a way to count days.

// Will return the number of days between the two dates passed in
function count_days( $a, $b )
{
// First we need to break these dates into their constituent parts:
$gd_a = getdate( $a );
$gd_b = getdate( $b );

// Now recreate these timestamps, based upon noon on each day
// The specific time doesn't matter but it must be the same each day
$a_new = mktime( 12, 0, 0, $gd_a['mon'], $gd_a['mday'], $gd_a['year'] );
$b_new = mktime( 12, 0, 0, $gd_b['mon'], $gd_b['mday'], $gd_b['year'] );

// Subtract these two numbers and divide by the number of seconds in a
// day. Round the result since crossing over a daylight savings time
// barrier will cause this time to be off by an hour or two.
return round( abs( $a_new - $b_new ) / 86400 );
}

Not much to say here, the function takes two time values and gets the difference between them in that last line by returning the absolute value of subtracting one from the other. But this difference is expressed in seconds, to express it as days we divide by 86,400 – the number of seconds in a day.

Now we can pass two dates to the function count_days and it will return an integer expressing the number of days between them.

Next we assign values to display in our web page depending on the date-related variables: whether we are showing spring or fall and how many days until DST.

// assign variables to be used by html based on whether this is a spring or fall page

if ($show_spring) {
$season = "spring";
$to_next = count_days( $next_spring, $time );
$to_previous = count_days( $nearest_fall_back, $time );
$associatedword = "forward";
$justpast = "fell back";
} else {
$season = "fall";
$to_next = count_days( $next_fall, $time );
$to_previous = count_days( $nearest_spring_ahead, $time );
$associatedword = "back";
$justpast = "sprung forward";
}

?>

That last line with the ?> lets the web server now that we’ve done what we need to for know with this PHP logic and we’re switching back to serving up some html.

<html>
<head>
<link rel="stylesheet" href="dst.css" type="text/css" media="screen, projection" />
<title>When is Daylight Savings Time?</title>
</head>
<body>

Pretty standard stuff. We are telling the browser this is an html document and accordingly it has a head with a link to a css file and a title which will display atop the browser window. We open the body tag which is where our text will appear.

<div id='<?=$season?>'>

First thing we do is create a div and give it an id using this syntax for inline php . $season is a variable we just assigned depending on whether we’re showing spring or fall. Here we have the the main container take on that value as its id, which we will reference it our css file.

<?php if ($to_next > 1) { ?>
<?=strtoupper($season)?>
<br />
<?=strtoupper($associatedword)?> IN<br />
<span class='thick'><span id='numdays'><?=$to_next?></span></span> DAYS<br />
<?php } elseif ($to_next == 1) { ?>
<?=strtoupper($season)?><br />
<?=strtoupper($associatedword)?> IN<br />
<span class='thick'><span id='numdays'>1</span></span> DAY<br />
<?php } else { ?>
<?=strtoupper($season)?><br />
<?=strtoupper($associatedword)?><br />
<span class='thick'><span id='numdays'>TODAY</span></span>
<?php }

Basically 3 things that can happen here. Either there’s more than 1 day to the next DST in which case we want to list the number of days with the word Days (plural), or there’s just 1 day to the next DST in which case we want to show just 1 Day (singular) or there’s 0 days between now and DST in which case we want to say it’s TODAY.

if ($to_previous == 1) { ?>
<div id='reminder'>You fell back 1 Day Ago.</div>
<?php } elseif ($to_previous <= 7 && $to_previous >= 1) { ?>
<div id='reminder'>You fell back <?=$to_previous?> Days Ago.</div> <?php } ?> </div>

We also check if we passed DST within the past seven days and if we have we include a small message letting people know in case they missed it. To see that in action here is what the site will show on November 4 2009.

And that’s all for the programming. There’s a little Google Analytics javascript include on the page also and later on we added this flying hourglass icon linking to our other when sites at whenderful.

Only we hadn’t added any of the css style definitions yet and our page without those would look like this.

The CSS is pretty straightforward, you could download it and let me know if you have any questions about it.

The only tricky issue css-wise was making the spacing of the taller font and the thick underline look right to match Cas’ design for the number of days.

Hope that wasn’t too long-winded. I’m here for any questions and I’ll try and blog a bit more about these sites in the near future.

Here’s a link to the full source code powering whenisdaylightsavingstime.com. Eat of this nourishment, go forth and make your own websites!

{ 1 comment… read it below or add one }

Hashim Warren July 25, 2009 at 10:52 pm

Hot. I love those simple websites that solve one problem. Thanks for sharing the knowledge.

Leave a Comment

Previous post:

Next post: