This document provides an overview of advanced date and time handling in PHP, including:
- Setting default timezones and parsing date strings
- Modifying dates and times using objects and intervals
- Working with timezones and the timezone database
- Iterating over periods defined by start date, interval, and end date
1 of 27
Downloaded 59 times
More Related Content
Advanced Date/Time Handling with PHP
1. Welcome!
Advanced Date/Time Handling
ZendCon - Santa Clara, US - Nov 2nd, 2010
Derick Rethans - derick@php.net - twitter: @derickr
http://derickrethans.nl/talks.html
http://joind.in/2232
2. About Me
Derick Rethans
¡ñ Dutchman living in London
¡ñ PHP development
¡ñ Author of the mcrypt, input_filter, dbus, translit
and date/time extensions
¡ñ Author of Xdebug
¡ñ Contributor to the Apache Zeta Components
Incubator project (formerly eZ Components)
¡ñ Freelancer doing PHP (internals) development
3. Problems
Timezones
¡ñ Most places have whole-hour timezone offsets
¡ñ Some places change timezones during the year
¡ñ One identifier can mean different zones: PST:
Pacific Standard Time, Pakistan Standard Time
EST: Eastern Standard Time (USA), Eastern
Standard Time (Australia) and Eastern Brazil
Standard Time
4. Timezone Support
¡ñ Bundled timezone database with 564 zones
¡ñ Not dependent on timezone abbreviations
¡ñ Timezones have the format: Continent/Location or
Continent/Location/Sublocation - Like:
Europe/Amsterdam, America/Indiana/Knox
5. Changing Timezone Definitions
¡ñ An updated database is released about 20 times a
year.
¡ñ Some of the changes are very sudden.
¡ñ PHP releases will therefore often have an
outdated version.
¡ñ The PECL extension timezonedb provides a drop
in replacement for the timezone database.
¡ñ pecl install timezonedb
6. Default Timezones
Setting a default timezone:
<?php
date_default_timezone_set("Europe/Oslo");
$ts = new DateTime("1978-12-22 09:15");
echo $ts->format("e");
?>
Getting a default timezone:
<?php
$default_identifier = date_default_timezone_get();
echo $default_identifier;
?>
Default timezone is 'guessed' in the following order:
¡ñ date_default_timezone_set() value
¡ñ TZ environment variable
¡ñ php.ini's date.timezone setting
¡ñ System's rendering of timezone abbreviation
7. Problems with timestamps and timezones
<?php
$date = strtotime( '2010-03-07 20:48:21 America/Toronto' );
echo date( 'Y-m-d', $date ), "n";
?>
Explanation:
2010-03-07 20:48:21 America/Toronto
1268012901 string is turned into a number
2010-03-08 01:48:21 Europe/London number is
converted to a date/time string using the default
timezone
8. Parsing Dates
Parsing strings for date time information by
instantiating a DateTime object:
<?php
$dt = new DateTime("2010-03-08 08:43:57");
?>
This function will not return the timestamp as an
integer, but instead returns a DateTime object which
is a wrapper around a 64 bit integer, which you can
access (as string) through:
<?php
$dt = new DateTime("2010-03-08 08:44:12");
echo $dt->format( 'U' ), "n";
?>
The DateTime class is what you can do the really
cool things with.
13. Using Timezones
The Timezone Object
Creating a timezone resource:
<?php
$tz = new DateTimeZone("Asia/Singapore");
?>
Using the timezone when parsing a string with a
date representation:
<?php
$tz = new DateTimeZone("Pacific/Honolulu");
$ts = new DateTime("1978-12-22 09:15", $tz);
?>
A passed timezone object does not override a parsed
timezone:
<?php
$tz = new DateTimeZone("Pacific/Honolulu");
$ts2 = new DateTime("1978-12-22 09:15 Europe/London", $tz);
echo $ts2->format( DateTime::RFC2822 );
?>
14. Using Timezones
Changing timezones
Using the timezone when parsing a string with a
date representation:
<?php
$tz1 = new DateTimeZone("Pacific/Honolulu");
$tz2 = new DateTimeZone("Australia/Melbourne");
$ts = new DateTime("1978-12-22 09:15", $tz1);
echo $ts->getTimezone()->getName(), ': ',
$ts->format(DateTime::RFC2822), "<br/>";
$ts->setTimezone($tz2);
echo $ts->getTimezone()->getName(), ': ',
$ts->format(DateTime::RFC2822), "<br/>";
?>
15. Timezones Utilities
Transition Times and Location Information
<?php
$tz = new DateTimeZone("Europe/Berlin");
$trs = $tz->getTransitions(
strtotime('1938-01-01 UTC'), strtotime('1948-01-01 UTC')
);
foreach ($trs as $tr) {
printf("%20s %7d %d %sn",
$tr['time'], $tr['offset'], $tr['isdst'], $tr['abbr']);
}
$loc = $tz->getLocation();
echo 'Info: ', join( ' - ', $loc ), "n";
19. Relative Time
"previous month" / "next month"
<?php
$date = new DateTime( '2010-01-31 15:48:21' );
echo $date->modify( 'next month' )->format( 'Y-m-d' ), "n";
?>
Explanation:
2010-01-31 15:48:21
2010-02-31 15:48:21 "next month" increases month
number by 1
2010-03-03 15:48:21 February only has 28 days, so
days are overflown into the next month
20. Relative Time
"first day next month"
<?php
$date = new DateTime( '2010-01-31 15:48:21' );
echo $date->modify( 'first day next month' )->format( 'Y-m-d' ), "n";
?>
Explanation:
2010-01-31 15:48:21
2010-02-31 15:48:21 "next month" increases month
number by 1
2010-03-03 15:48:21 February only has 28 days, so
days are overflown into the next month
2010-03-04 15:48:21 "first day" adds one more day
21. Relative Time
"first day *of* next month"
<?php
$date = new DateTime( '2010-01-31 15:48:21' );
echo $date->modify( 'first day of next month' )->format( 'Y-m-d' ), "n";
?>
Explanation:
2010-01-31 15:48:21
2010-02-31 15:48:21 "next month" increases month
number by 1
2010-02-01 15:48:21 "first day of" resets the day
number to 1
22. Relative Time
"last day of third month"
<?php
$date = new DateTime( '2010-01-31 15:48:21' );
echo $date->modify( 'last day of third month' )->format( 'Y-m-d' ), "n";
?>
Explanation:
2010-01-31 15:48:21
2010-04-31 15:48:21 "third month" increases month
number by 3
2010-05-00 15:48:21 "last day of" resets the day
number to 0 and increases the month number by 1
2010-04-30 15:48:21 Day count is less than 1, so the
algorithm corrects this to a proper date
23. Periods (PHP 5.3)
Initializing a period
<?php
// start, interval and count
$db = new DateTime( '2008-07-31' ) ;
$di = DateInterval::createFromDateString( 'next weekday' );
$p = new DatePeriod( $db, $di, 3 );
// start, interval and end
$de = new DateTime ( '2008-08-05' );
$p = new DatePeriod( $db, $di, $de );
// ISO 8601 string
$s = "2008-10-04T20:56:18Z/P0000-00-20T03:15:54/2008-12-22T00:00:00Z";
$p = new DatePeriod( $s );
?>
24. Periods (PHP 5.3)
Iterating over a period
<?php
$db = new DateTime( '2008-12-31' );
$de = new DateTime( '2009-12-31' );
$di = DateInterval::createFromDateString(
'third tuesday of next month'
);
$dp = new DatePeriod(
$db, $di, $de, DatePeriod::EXCLUDE_START_DATE
);
foreach ( $dp as $dt )
{
echo $dt->format( "F jSn" );
}
?>