When working with dates, time and calendars it becomes a pretty common requirement to compare dates-Testing whether a date occurs after or before one date, whether an event occurs between two specific times, etc. The easiest way to work with dates in PHP is with the DateTime object.
Obviously for us (as humans) it is pretty easy to see that my party is not during my shift. On the other hand for the computer to see this is a whole other issue.
A DateTime object can be instantiated as such:
|
1 |
$date = new DateTime(); |
And is described as:
|
1 |
new DateTime( [ string $time = "now" [, DateTimeZone $timezone = NULL ]] ); |
The string parameter can accept any string that can be converted by strtotime (Read the Date and Time Formats section for a full explanation).
So, back to the instantiation. I want to create an DateTime object for Halloween (October, 31st 2010):
|
1 |
$halloween = new DateTime( '2010-10-31', new DateTimeZone( 'America/Denver' ) ); |
This would yield a DateTime object that references 10/31/2010 in the America/Denver timezone (Maybe more on timezones later). This can be verified by using the DateTime object’s format() method:
|
1 2 |
$halloween = new DateTime( '2010-10-31', new DateTimeZone( 'America/Denver' ) ); print $halloween->format( 'Y-m-d' ); |
This gives the following result:
Now lets look to see if today is before Halloween. Today is 10/27/2010 which is clearly before Halloween. It should first be noted that strings should never be used to compare dates. Because of the method PHP uses when comparing strings in an if statement the following code:
|
1 2 3 4 |
$a = (int) '10/27/2010'; $b = (int) '10/31/2010'; print "( $a > $b )<br />"; var_dump( ( $a > $b ) ); |
Results in:
This is because PHP will first attempt to convert the strings to numbers and compare them numerically. And since 10 is not greater than 10 we get false.
To compare the dates correctly, what needs to take place is
Our dates are already in a DateTime object and are therefore in the same format.
Next we need a numeric value of the date with which we can make a comparison. The best way to do this is to use the Unix Epoch Timestamp. A Unix Timestamp is the number of seconds that have elapsed since January, 1st 1970. To convert a date to it’s timestamp, we simply use the format() method with the string 'U':
|
1 2 |
$halloween = new DateTime( '2010-10-31', new DateTimeZone( 'America/Denver' ) ); print $halloween->format( 'U' ); |
Which yields:
Now we can correctly compare the two dates:
|
1 2 3 4 5 6 7 8 9 |
$halloween = new DateTime( '2010-10-31', new DateTimeZone( 'America/Denver' ) ); $today = new DateTime( 'now', new DateTimeZone( 'America/Denver' ) ); print "( {$halloween->format( 'U' )} > {$today->format( 'U' )} )<br />"; if ( $halloween->format( 'U' ) > $today->format( 'U' ) ) { print "Halloween has not passed yet."; } else { print "Halloween has already passed."; } |
Which gives us, as we would expect:
Now as you would expect comparing for the reverse, namely that a date occurs after a date, is pretty much the same thing. However now I would like to look at checking to see if a date or time is between two different dates and times. Doing so should be easy now.
I want to see if my Halloween party is scheduled during my scheduled work shift. First off we need some facts:
It will be cutting it close.
Obviously for us (as humans) it is pretty easy to see that my party is not during my shift (and it better not be since I’m hosting the party). On the other hand for the computer to see this is a whole other issue.
We will work this out in a similar fashion to the last example:
First lets set up the DateTime objects:
|
1 2 3 4 5 |
<?php $shiftStart = new DateTime( '2010-10-31 10:00', new DateTimeZone( 'America/Denver' ) ); $shiftEnd = new DateTime( '2010-10-31 19:00', new DateTimeZone( 'America/Denver' ) ); $party = DateTime( '2010-10-31 19:30', new DateTimeZone( 'America/Denver' ) ); ?> |
Next we will convert them to Unix timestamps and compare them:
|
1 2 3 4 5 6 7 8 9 10 11 12 |
<?php $shiftStart = new DateTime( '2010-10-31 10:00', new DateTimeZone( 'America/Denver' ) ); $shiftEnd = new DateTime( '2010-10-31 19:00', new DateTimeZone( 'America/Denver' ) ); $party = new DateTime( '2010-10-31 19:30', new DateTimeZone( 'America/Denver' ) ); if ( $party->format( 'U' ) >= $shiftStart->format( 'U' ) && $party->format( 'U' ) <= $shiftEnd->format( 'U' ) ) { print "You work during your party. That sucks."; } else { print "You don't work during your party. FTW!"; } ?> |
Result:
And I could not be happier that I don’t work during my party.
Hope this short tutorial helped someone. =P Questions-Leave them in the comments.
Love your site man keep up the good work
such a long poster
Hehehe. You’re so right.