How to deal with Date and Time in WordPress

4 min read
1031

If you want to shake the developer’s faith, ask them to do something with the dates. It’s always challenging. In WordPress, it’s in twice tricky.

WordPress has many settings related to date and time. These settings allow site owners easily modify timezone, date and time formats, and the first day of the week.

How to keep your date and time on your website customizable and translatable in WordPress? How do we avoid primary date and time errors? - WP Punk

Further, I will explain how to deal with these settings in different cases.

Translations

Some date formats include months or days names that should be translatable. For instance, the F format should return January for the English website and enero for the Spain one.

It would be nice if you use the wp_date or date_i18n WordPress functions to keep dates translatable.

Difference between these functions: the date_i18n is the legacy function with backward compatibility for old code. Honestly, I don’t see any practical reason to use the date_i18n function nowadays, and you can use the wp_date everywhere. However, you must carefully test your changes when replacing the date_i18n with wp_date because it can take some side effects.

Format

Since WordPress has settings for date and time formats, in most cases, we have to get them from the options:

$date_format      = get_option( 'date_format' );
$time_format      = get_option( 'time_format' );
$date_time_format = sprintf( '%s %s', get_option( 'date_format' ), get_option( 'time_format' ) );

Time Zones

Time zones and time shifting may be the most complicated part when dealing with dates.

WordPress stores the time zones in the number of hours that needs to be shifted from UTC+0. For instance, India has UTC+05:30, and in the database, it’s 5.5, but California has UTC-08:00, and in the database is -8.

So, the gmt_offset option can be positive or negative, integer or fractional number. Despite everything sounding very scary, it is actually very convenient to use in code.

For example, let’s find the current date and time despite the website settings:

$offset = (float) get_option( 'gmt_offset' ) * HOUR_IN_SECONDS;

Custom Function

To sum up, we can create our own function that allows you don’t remember all of these options’ names and just always use it in your codebase:

function wppunk_datetime_format( $timestamp, $format = '', $is_utc = false ) {

	if ( $format === '' ) {
		$format = sprintf( '%s %s', get_option( 'date_format' ), get_option( 'time_format' ) );
	}

	$timezone = $is_utc ? 'UTC' : '';

	return wp_date( $format, $timestamp, timezone );
}

First Day of the Week

If you have logic in your code that relates to data for a specific week, you need to consider that WordPress has the start_of_week option. For example, the number of sent messages in the past week. When did last week start? On Sunday? On Monday? Who knows?

Generally, the option returns a number between 0 and 6, where 0 is Sunday, and 6 is Saturday.

$start_of_week = (int) get_option( 'start_of_week', 0 );

Storing Date and Time in the Database

Never store the date and time in WordPress format, as well as with offsets. It just doesn’t make sense. The data becomes outdated whenever you change WordPress’s date and time-related settings.

In a database, you only have one correct option is storing date and time in SQL format – YYYY-MM-DD HH:MI:SS, e.g. 2023-01-28 14:39:12.

Firstly, it’s human-readable, and those who watched your plain data in SQL can understand where it was submitted without extra steps. Secondly, SQL works pretty well with its date format, and you can make any date changes directly in SQL queries.

Date and Time SQL Queries

In most cases, when you need to get some date period, you can use WordPress functions or objects e.g. WP_Query, get_posts, etc. However, you must write your own SQL queries when dealing with custom tables. And sometimes, these queries are depended on dates.

For instance, I need to get the entries that were made on January 28th. For UTC+0, the query is:

SELECT * FROM records WHERE date >= 28.01.2023 00:00:00 AND date < 29.01.2023 00:00:00

The query is super simple, but what if a site owner lives in California (UTC-08:00)?

How to keep your date and time on your website customizable and translatable in WordPress? How do we avoid primary date and time errors? - WP Punk

The day in California starts 27.01.2023 at 16:00:00 and ends 28.01.2023 at 16:00:00. You have to calculate the offset on the PHP side:

$offset          = (float) get_option( 'gmt_offset' ) * HOUR_IN_SECONDS;
$timestamp_start = date_format( date_create( '2023-01-28' ), 'U' );
$timestamp_end   = date_format( date_create( '2023-01-29' ), 'U' );

$wpdb->query(
	$wpdb->prepare(
		'SELECT * FROM records WHERE date >= %s AND date < %s',
		date_format( $timestamp_start + $offset, 'Y-m-d H:i:s' ),
		date_format( $timestamp_end + $offset, 'Y-m-d H:i:s' )
	)
);

Or you can calculate it on the SQL side. Fortunately, SQL has a lot of instruments that help you work with dates:

$wpdb->query(
	$wpdb->prepare(
		'SELECT * FROM records WHERE date >= DATE_ADD(%1$s, INTERVAL %3$d MINUTE) AND date < DATE_ADD(%2$s, INTERVAL %3$d MINUTE)',
		date_format( date_create( '2023-01-28' ), 'Y-m-d H:i:s' ),
		date_format( date_create( '2023-01-29' ), 'Y-m-d H:i:s' ),
		get_option( 'gmt_offset' ) * HOUR_IN_SECONDS
	)
);

Next point, don’t use the NOW() function in SQL. SQL servers have their own timezone and offsets. To get the current time, you can use the UTC_TIMESTAMP function instead.

I hope next time it will be easier for you to deal with date and time in WordPress after reading the article. Anyway, if you have any questions, you can ask them in the comments or on Twitter.

If the content was useful, share it on social networks

Leave a Reply

Your email address will not be published. Required fields are marked *

Subscribe to news. I promise not to spam :)
Follow me, don't be shy