Developer

PHP dates and times

Take a look at PHP's functions that help you display and manipulate dates and times.

By David Sklar and Adam Trachtenberg

PHP has a bunch of handy functions to help you display and manipulate dates and times.

To display a date or time formatted a certain way, use date(). It takes two arguments: the format that describes how to print the date and the time stamp that represents the date you want to print. The time stamp has to be in the seconds-since-1970 form described above. (If you want to use the current time, you can just use the function time(), which returns the time stamp for "right now.") date() has a ton of formatting options, such as the strftime() function in C or the POSIX::strftime() function in Perl.

<?php
$birthday_stamp = mktime(19,45,0,3,10,1975);
$birthday_formatted = date('F d, Y - g:i a',$birthday_stamp);

echo "David was born on $birthday_formatted."
?>

will produce

David was born on March 10, 1975—7:45 p.m.

Of course, if you have a specific date in mind, fancy formatting functions aren't so useful because you know what the formatted text would be in advance. These functions can be handier in, say, printing part of a form where you want users to pick a date:

<SELECT NAME="when">
<?php
$d = time();
for ($i = 0; $i < 10; $i++) {
echo '<OPTION VALUE="'.$d.'">'.date('F d',$d);
$d += 86400;
}
?>
</SELECT>

This prints a select box with ten choices—today and each of the next nine days. Before the loop starts, we store the current time in $d. Each <OPTION> gets echoed out, with its value set to the time as Unix time stamp and the displayed text set to month and day ("July 27," "July 28," and so on.) After displaying the <OPTION>, $d gets incremented by 86,400 (how many seconds there are in a day—24 hours * 60 minutes * 60 seconds).

By combining mktime() and date() you can find out information about a particular user-entered date. What if you wanted to find the first Sunday (or any other day of the week) after a certain date? First, make a function that will print the appropriate form:

<?php


function display_form() {
  global $PHP_SELF;

$dotw = array('Sunday','Monday','Tuesday','Wednesday','Thursday',
     'Friday','Saturday');
$months = array( 1 => 'January','February','March','April','May','June',
                'July','August','September','October','November','December');
?>
<FORM TARGET="<?php echo $PHP_SELF; ?>" METHOD=GET>
Find the first
<SELECT NAME="dotw">
<?php
for ($i = 0; $i < 7; $i++) {
    echo "<OPTION> $dotw[$i]";
}
echo '</SELECT> after <SELECT NAME="month">';
for ($i = 1; $i <= 12; $i++) {
    echo "<OPTION VALUE=\"$i\"> $months[$i]";
}
echo '</SELECT> <SELECT NAME="day">';
for ($i = 1; $i <= 31; $i++) {
    echo "<OPTION> $i";
}
echo '</SELECT>, <SELECT NAME="year">';
$start_year = date('Y') - 10;
$end_year = $start_year + 20;
for ($i = $start_year; $i <= $end_year; $i++) {
    echo "<OPTION> $i";
}
echo '<INPUT TYPE="HIDDEN" NAME="stage" VALUE="process">';
echo '</SELECT> <INPUT TYPE="SUBMIT" VALUE="Do it!"7></FORM>';
}

?>

There are a few things in this function that we haven't discussed before. The $months array is written a little differently because we want the index of January to be 1, not 0. Also, it's much easier to generate parts of this form programmatically instead of explicitly listing all form element values, so the only part of display_form() that's not in PHP mode is the stuff at the top that begins the form. Also, setting $start_year and $end_year using date('Y') gives us a range for years that's ten years before or after the current year.

Here's the function to process the form:

<?php

function process_form() {
    global $dotw;
    global $month;
    global $day;
    global $year;
    $timestamp = mktime(0,0,0,$month,$day,$year);

    $next_dotw = '';
    $next_timestamp = $timestamp;

    while ($next_dotw != $dotw) {
      $next_timestamp += 86400;
      $next_dotw = date('l',$next_timestamp);
    }

    $formatted_first = date('F d, Y',$timestamp);
    $formatted_next = date('F d, Y',$next_timestamp);
    echo "The first $dotw after $formatted_first is $formatted_next.";
}
?>

First, this converts the supplied date to a Unix time stamp. If we wanted to be more paranoid and careful, we could add some code that would make sure that all of the supplied values are within acceptable ranges, but that's not necessary here.

Then the loop continues while the day of the week for the "next day" we're looking for is different than the day of the week that the user supplies. While they're different, the "next day" gets incremented (there's that 86400 seconds = 24 hours * 60 minutes * 60 seconds again) and its day of the week value is recalculated.

Once the two values are equal, process_form() prints out a nice message:

The first Sunday after June 25, 1999 is June 27, 1999.

We also need the familiar main loop to tie it together:

<?php

if (empty($stage)) { display_form(); }
else { process_form(); }

?>

Date handling code sometimes needs to be more complicated to handle daylight savings time and different time zones, but date() and mktime() are the basic tools for going back and forth between Unix time stamps that are easily manipulated in algorithms and human-readable ways of expressing date and time. date() and mktime() operate on times in the local time zone of your machine. If you want to deal with times in Greenwich Mean Time (GMT), you can use gmdate() and gmmktime().

For example, for a machine in eastern daylight time, which is four hours behind GMT:

<?php

$today = mktime(12,0,0,6,25,1999);
echo 'Here it is '.date('g:i:s a, F d, Y',$today);
echo '';
echo 'In GMT it is '.gmdate('g:i:s a, F d, Y',$today);

?>

will produce

Here it is 12:00:00 pm, June 25, 1999
In GMT it is 4:00:00 pm, June 25, 1999
David Sklar is the CTO of Student.Net Publishing.

Adam Trachtenberg is the Vice President for Production of Student.Net Publishing.

Editor's Picks

Free Newsletters, In your Inbox