Published on by Chris Mospaw
Keeping track of time in any modern computer system is a complex affair. Not only does one have to consider the timezone of the server, but the timezone of the user, the user's system, the user's browser, and systems such as PHP and MySQL, each with their own separate time settings. Even though time keeping machinery is extremely accurate, many applications have a haphazard approach to determining what time it is.
WordPress does a good job of keeping track of what time it is, when something happened, and how that should be represented as data or to the current user. However, It's easy to forget that WordPress takes care of it for you and use something else. By working outside of WordPress, tracking time can quickly become complicated and frustrating.
We recently needed to add “to the minute” granularity to events in a theme that previously only needed daily granularity. The theme code was storing the scheduled event meta data using the PHP time() function in WordPress. Unfortunately, time() caused the wrong time value to be stored when the minutes mattered. The time stored was offset by six hours, causing scheduled events not to fire on time. A hint to the source of this problem is that the server time was set to Eastern US (6 hours behind UTC when this evaluation was being done).
This caused us a good deal of code tracing to figure out the best way to deal with the time offset. In solving the issue, we knew the one thing not to do was simply remove six-hours worth of seconds from time()
in this part of the code. After all, the offset time would be changing twice a year when Daylight Savings time came and left. We had to find a solution.
Rolling Your Own: Bad Idea
Timezones are incredibly complicated and ever-changing. Add in daylight savings and a recipe for madness is born. Fortunately, this problem is continually being solved by other people. Whenever possible, do not try to deal with timezones on your own: it will go wrong. This isn't a lack of faith in any one person's coding abilities, but an indicator of how large and complex the issue is. In this case, it’s best to let the work of others take care of it instead.
Search Google for “time zone programming problems” to get lots of examples.
WordPress Changes and Manages Time for Us
While tracing the “timezone offset” issue, we discovered that WordPress handles time well. WordPress ensures that within WordPress, time values will be consistent.
When running, the first thing WordPress does is set the local PHP timezone to UTC. So if a server on US Eastern Time, and PHP is configured with the same timezone, WordPress will override it. Each blog has a timezone setting in “Admin >> General Settings >> Timezone” which is stored that blog's gmt_offset
option. WordPress uses this option, if present, to calculate and adjust times so that they're represented in the blog's timezone.
Each blog in a network has its own setting, so one installation can serve blogs in different timezones. If there are many sites in a network that all need to have the same timezone set, they will each need to be set manually. If there is a large network, calls to get_option( 'gmt_offset' )
can be filtered if an automated timezone setting is desired (as opposed to manually changing a lot of options for the individual blogs).
Fixing time()
WordPress provides a number of time functions, most notably current_time()
, that normalizes blog time based on the current blog's set timezone (or a default back to UTC if none is set).
The calls in the theme to PHP time()
mentioned above were easily fixed by changing them to WordPress's current_time()
instead. This eliminated the need to translate the time to the current timezone since WordPress had already done that. We have also seen code that used calls to MySQL to obtain consistent time. Changing it to use current_time()
can help when ironing out your time wrinkles or inconsistencies.
In General
When in the WordPress ecosystem, use WordPress's time functions as opposed to system time, PHP, or MySQL.
Reference
current_time( $type, $gmt = 0 )
Return the blog's current local time in the specified format.
$type
is ‘mysql', ‘timestamp', or a PHP date format (since WordPress 3.9).
$gmt
defaults to local blog's setting if false (0) or to GMT if true (1).
Codex:
http://codex.wordpress.org/Function_Reference/current_time
get_the_time( $format, $post )
Return the time of the current post for use in PHP.
$format
uses the formatting referenced below.
$post
defaults to the current post or will take a post ID or object.
Codex:
http://codex.wordpress.org/Function_Reference/get_the_time
Formatting Date and Time in WordPress
Some of WordPress's time functions accept a parameter that allows one to determine how the date is going to be displayed. The format string is a template in which various parts of the data are combined to generate a date in the format specified.