Events Manager is timezone aware as of version 5.8.2.
You can create events in different timezones around the world and these events will not appear under upcoming events lists if the events have passed, wherever they may be in the world. iCal feeds will also include Timezone information which can be parsed by calendar/email clients.
From a user perspective, event admins and site visitors may notice some subtle changes. Site admins will see an option to select a timezone whilst creating and editing events, and will also be able to output timezone information with new placeholders.
Event creators and admins will also notice that when viewing events in the admin area, any event that is not in the same timezone as your blog (which is found in WP Dashboard > General > Settings) will show a little information icon with a tip showing the timezone of that specific event.
Every event will now have its own timezone. If you would like to have a different timezone for your events (for example, if you never had paid attention to timezones when creating your first events), you can do so from Events > Settings > Admin Tools. Do bear in mind, however, that this will overwrite ALL events, even those with custom timezones.
Transitioning from earlier versions of Events Manager
All events created prior to 5.8.2 will adopt the blog local timezone. Future events will default to the default setting in Events > Settings > General > General Options, which will by default be the same timezone as the local blog timezone.
See further up for information on changing your event timezones in bulk, in case you hadn’t set your blog timezone to a local time.
Developer Information
For developers, the way we store and access date-related information has changed. Most notably, we have introduced two new classes called EM_DateTime and EM_DateTimeZone, and also added three new database fields into the wp_em_events table.
Database Changes
Three new fields are introduced to the wp_em_events table, which are event_start, event_end and event_timezone.
These first two fields are mysql DATETIME values representing UTC equivalent start/end date/times for the event. These two fields will be used for searching by date when using past and future scopes, so that an event that happened in Auckland at 10am won’t still show on a blog with a London timezone at 10am that same day. Date-specific searches such as by month or specific date ranges will still use local dates to search.
event_timezone represents the timezone of that specific event, in the format of an Olson timezone or UTC manual offset (as used by WordPress)
These fields are also included in the wp_postmeta tables for each event, and whilst _start_ts and _end_ts are still there, they will not be used anymore and eventually will be deleted. Additionally, we have added _event_start_local and _event_end_local which are DATETIME representations of the start and end of the event in local time, which is used for sorting and filtering in the admin area and for WP_Query lookups where timezone isn’t a consideration for lists.
Code Changes
Our new classes are extensions of the default PHP DateTime and DateTimeZone classes with some added improvements allowing for shorter method building and also support for manual UTC offsets as supported by WordPress. Dates and times stored by Events Manager within the Event, Booking and Ticket objects should now be accessed using functions which return a valid EM_DateTime object in the relevant timezone of the event. We recommend developers take a look at these new classes, stored in classes/em-datetime.php
, which are fully documented inline.
We will go through each of these objects and highlight how certain class properties previously used throughout the plugin and likely in your code, and how to modify them for our new standards.
The general rule is this:
- The EM_DateTime properties should ALWAYS be used for reference, display and comparison.
- The only exceptions to 1) is if you are specifically after raw mysql date/time value and do not intend on manipulating that information for anything else.
- Checking if a value is set such as via empty() is acceptable in certain situations, but we recommend retrieving the EM_DateTime object and checking its valid property instead.
- If you need to change the value of a property (for example, if you are updating an event to the database), you can still directly set these properties.
Note that all these properties do have a fallback and will still output data as previously expected, internally though, it will be providing that information via their respective EM_DateTime objects.
EM_Event (and EM_DateTime examples)
Previously, the following object properties were used in almost every way with regards to referencing and displaying event start and end information:
- event_start_date
- event_end_date
- event_start_time
- event_end_time
- event_rsvp_date
- event_rsvp_time
- start
- end
- rsvp_end
It was common to compare dates to see if events were on the same day, or use the start/end properties to pass onto date() functions for formatting dates. This isn’t necessary anymore and instead all this information can be obtained by the start(), end() and rsvp_end() functions.
These objects all work the same way, and we’ll provide some initial examples with respect to this:
$EM_Event->start()->getDate(); //can be used instead of: $EM_Event->event_start_date; $EM_Event->end()->format('d/m/Y'); //should be used instead of: date('d/m/Y', $EM_Event->start);
Notes about timestamps
It’s also important to note that timestamps are now real UTC timestamps. Previous versions of Events Manager would generate timestamps with offsets relative to blog timezones so that they could be used when displaying formatted dates using the timezone unaware date() and date_i18n() functions.
Previously, you would want to check if an event is past like this:
if( $EM_Event->start > current_time('timestamp') ) ...
Whereas now you would do this:
if( $EM_Event->start()->getTimestamp() > time() ) ....
Whilst the earlier line of code will still work, because EM_Event will still return ‘start’ as an offset timestamp, we still recommend switching over.
Accessing new properties and saving old ones
Finally, the new UTC times stored in wp_em_events and loaded as properties event_start, event_end and event_timezone are protected properties and cannot be accessed or manipulated directly. If you would like to get or set the timezone of an event, you can use the following:
$EM_Event->getTimezone()->getName(); //getTimezone() returns an EM_DateTimeZone object $EM_Event->setTimezone('America/New_York'); //you can supply a string, EM_DateTimeZone or DateTimeZone object.
If you would like to get the UTC-equivalent end time of an event, you would simply do this:
$EM_Event->start(true)->getDateTime(); //passing true to start() returns the object in UTC timezone
If you change the time of an event via EM_Event->event_start_time, or change the timezone of an event the UTC date/time value will be reset and recreated relative to the new time should you wish to save that event.
So, for example, for an event in London time during DST (i.e. UTC + 1 hour)
$EM_Event->start()->getDateTime(); //currently 2017-07-01 13:00:00 or 12:00:00 UTC time $EM_Event->event_start_time = 15:00:00; $EM_Event->start(true)->getTime(); //UTC time will return 14:00:00 $EM_Event->setTimezone('Europe/Madrid'); //Local time remains 15:00:00 but Madrid DST timezone is now UTC+2 $EM_Event->start(true)->getTime(); //UTC time will return 13:00:00 $EM_Event->save(); //event_start time will now be saved as 13:00:00, and event_end time will also be changed relative to new timezone
EM_Ticket
Tickets have start and end times for when they are available for sale:
- ticket_start
- ticket_end
These times are represented as local time for the event. Setting and getting these objects will still produce the same result as before.
They should, however, now be accessed via the start() and end() methods which behave exactly the same as the EM_Event methods, the only difference being the timezone is obtained from the event the ticket belongs to. You can use these EM_DateTime objects to check availability irrespective of timezone, such as:
if( $EM_Ticket->start()->getTimestamp() > time() && $EM_Ticket->end()->getTimestamp() < time() ) .... //tickets are on sale right now, now check space availability
EM_Booking
Bookings have a booking date associated with them marking the date it was made, stored as booking_date. This is stored as a UTC date, and can be retrieved by the date() method and will return a EM_DateTime object with a timezone belonging to the event it was booked.
In this case, it may be useful to show the booking date and time relative to the blog timezone. So, an event with a New York timezone was booked at 9am on a London-based blog for example. You may want to show UK time like so:
$EM_Booking->date()->setTimezone('Europe/London')->format('d/m/Y H:i');