👋 Please note that this implementation uses cookies! If you would like to use this on your website you will need to include information in your cookie policy and ask for user consent!

The Events Calendar gives you the option to show the events on your website in your websites time zone or in the time zone where the event is taking place. This can be controlled by a setting that can be found under the Events → Settings → Display tab. You can read more about this setting in this article.

Time Zone settings of The Events Calendar

Showing the events in the time zone of the visitor is a bit more tricky as we somehow need to get that information, preferably automatically. Fortunately JavaScript can help us in that as it can grab the time zone of the visitor’s browser.

This is where the user consent comes in! We need to ask for the visitors permission so that we can grab that piece of information and store it in a cookie. Implementing the cookie consent is beyond the scope of this tutorial. It is something that you will need to implement on your own if you decided to use this solution.

Enough talk…

Here I’m going to show you how you can implement this on the single event page using both the Classic or the Block editor. (You can find the relevant setting under Events Settings → General tab Activate Block Editor for Events) The approach would be similar on different calendar views as well. (There are some notes about this at the end of this tutorial.)

1. The template override

We want this functionality to remain available even after a plugin update, so we will make use of the template override system of The Events Calendar.

If you are using the Classic editor

Grab the following file:

wp-content/plugins/the-events-calendar/src/views/single-event.php

Make a copy of it and place it in this folder:

wp-content/themes/[your-child-theme]/tribe-events/single-event.php

If you are using the Block editor

Grab the following file:

wp-content/plugins/the-events-calendar/src/views/blocks/event-datetime.php

Make a copy of it and place it in this folder:

wp-content/themes/[your-child-theme]/tribe/events/blocks/event-datetime.php

Placing the file under your child theme folder will ensure that these changes will stay in place in the event of a theme or a plugin update.

Please note though that if the original template file receives an update you might need to implement those changes in your override as well.

2. The code

Open the override file for editing and look for this line:

$event_id = get_the_ID();

For the Classic Editor, the line is:

$event_id = Tribe_Events_Main::postIdHelper(
get_the_ID() );

Below that line add the following piece of code (line included for reference):

$event_id = get_the_ID();

/**
 * Setting up the cookie if it doesn't exist yet and grabbing the browser time zone string.
 */
if ( ! isset( $_COOKIE['tribe_browser_time_zone'] ) ) { ?>
	<script type="text/javascript">
		if ( navigator.cookieEnabled ) {
			document.cookie = "tribe_browser_time_zone=" + Intl.DateTimeFormat().resolvedOptions().timeZone + "; path=/";
		}
	</script>
<?php }

/**
 * Calculating the event start time and time zone based on the browser time zone of the visitor.
 */

// Setting default values in case the cookie doesn't exist.
$user_time_output = "<small>Your time zone couldn't be detected. Try <a href=''>reloading</a> the page.</small>";
$browser_time_zone_string = "not detected";

if ( isset( $_COOKIE['tribe_browser_time_zone'] ) ) {
	// Grab the time zone string from the cookie.
	$browser_time_zone_string = $_COOKIE['tribe_browser_time_zone'];

	// Grab the event time zone string.
	$event_time_zone_string = Tribe__Events__Timezones::get_event_timezone_string( $event_id );

	// Grab the event start date in UTC time from the database.
	$event_start_utc = tribe_get_event_meta( $event_id, '_EventStartDateUTC', true );

	// Set up the DateTime object.
	$event_start_date_in_utc_timezone = new DateTime( $event_start_utc, new DateTimeZone( 'UTC' ) );

	// Convert the UTC DateTime object into the browser time zone.
	$event_start_date_in_browser_timezone = $event_start_date_in_utc_timezone->setTimezone( new DateTimeZone( $browser_time_zone_string ) )->format( get_option( 'time_format' ) );

	// Grab the time zone abbreviation based on the browser time zone string.
	$browser_time_zone_abbreviation = Tribe__Timezones::abbr( 'now', $browser_time_zone_string );

	// Compile the output string with time zone abbreviation.
	$user_time_output = $event_start_date_in_browser_timezone . " " . $browser_time_zone_abbreviation;

	// Compile the string of the time zone for the tooltip.
	$browser_time_zone_string .= ' detected';
}

3. The markup

We’re still working in the same file.

Classic editor

Look for this line:

<?php echo tribe_events_event_schedule_details( $event_id, '<h2>', '</h2>' ); ?>

Add the following below the line (line included for reference):

<?php echo tribe_events_event_schedule_details( $event_id, '<h2>', '</h2>' ); ?>

<?php
/**
 * Adding the event start time in the visitor's time zone.
 */
if ( ! tribe_event_is_all_day( $event_id ) ) {
	echo "<div class='tribe-events-schedule--browser-time-zone'><p>";
	echo "Start time where <span style='text-decoration-style: dotted; text-decoration-line: underline; cursor: help;' title='This is based on your browser time zone (" . $browser_time_zone_string . ") and it might not be fully accurate.'>you are</span>: " . $user_time_output;
	echo "</p></div>";
}
?>

Block editor

Go to the end of the file and paste the code between the </h2> and the closing </div> tags, like this (lines included for reference):

	</h2>
	<?php
	/**
	 * Adding the event start time in the visitor's time zone.
	 */
	if ( ! tribe_event_is_all_day( $event_id ) ) {
		echo "<div class='tribe-events-schedule--browser-time-zone'><p>";
		echo "Start time where <span style='text-decoration-style: dotted; text-decoration-line: underline; cursor: help;' title='This is based on your browser time zone (" . $browser_time_zone_string . ") and it might not be fully accurate.'>you are</span>: " . $user_time_output;
		echo "</p></div>";
	}
	?>
</div>

If you would like you can change the content of that sting of course. If you are running your website in a different language, then you will probably want to do that as there are no translations provided for this custom part.

Note, with the above code the time will not show up for all day events. You can remove that constraint if you would like or you can add a similar one for multi-day, recurring, featured events based on your needs.

4. The magic …

After you have saved the file the event pages should look like this:

Example output using the Classic editor

Cookie data

As pointed out at the beginning of this tutorial this implementation uses a cookie for which you might need to ask for user consent. This us up to you to implement.

The name of the cookie is:

tribe_browser_time_zone

It will store the value of the time zone string of the visitor’s browser. Here are a couple of examples what it may look like:

Europe/Zurich
America/New_York
Asia/Hong_Kong

The cookie is valid for the full domain of the website and does not have a set expiry date. It automatically expires when the browser is closed.

Implementing in other views

The code uses the post ID of the specific event. In the above example this was already available as $event_id. In other templates this might be different though so the code might need to be adjusted. One of the possibilities is adding a line like this in the beginning:

$event_id = $event->ID;

If you would like to implement this for the list view with the updated calendar design this would be a good file:

the-events-calendar/src/views/v2/list/event/date.php

Enjoy!