Should the WordPress scheduler use datetime-local?
There's a brilliant post by WordPress about how they've optimised some of the backend code to make it more efficient. So here's a suggestion for something else which can be optimised.
If you want to schedule a blog post to be published later, you have to use this WordPress control:

I find it mildly annoying. I don't get why part of it is a dropdown. And the number fields don't pop up my phone's number keypad. And I have to look at a different calendar if I want to schedule something for a Saturday.
But how efficient is it on the back-end?
Every time you save, schedule, or edit a blogpost - this is what is POSTed to the server:
mm=09
jj=04
aa=2023
hh=12
mn=34
ss=20
Interestingly, the "seconds" are from a hidden input field! <input type="hidden" id="ss" name="ss" value="18" />
WordPress can't rely on a front-end control for validation. So here's the code that goes into checking whether a POSTed date is valid:
PHP
$aa = $post_data['aa'];
$mm = $post_data['mm'];
$jj = $post_data['jj'];
$hh = $post_data['hh'];
$mn = $post_data['mn'];
$ss = $post_data['ss'];
$aa = ( $aa <= 0 ) ? gmdate( 'Y' ) : $aa;
$mm = ( $mm <= 0 ) ? gmdate( 'n' ) : $mm;
$jj = ( $jj > 31 ) ? 31 : $jj;
$jj = ( $jj <= 0 ) ? gmdate( 'j' ) : $jj;
$hh = ( $hh > 23 ) ? $hh - 24 : $hh;
$mn = ( $mn > 59 ) ? $mn - 60 : $mn;
$ss = ( $ss > 59 ) ? $ss - 60 : $ss;
$post_data['post_date'] = sprintf( '%04d-%02d-%02d %02d:%02d:%02d', $aa, $mm, $jj, $hh, $mn, $ss );
$valid_date = wp_checkdate( $mm, $jj, $aa, $post_data['post_date'] );
if ( ! $valid_date ) {
return new WP_Error( 'invalid_date', __( 'Invalid date.' ) );
}
$post_data['post_date_gmt'] = get_gmt_from_date( $post_data['post_date'] );
That's quite complex. Luckily, there is an easier way.
There is a specific HTML input element for entering dates and times. You write <input type="datetime-local">
and you get:
That will show a browser's native datetime picker and it works on every browser. It works brilliantly on mobile and desktop. It makes it much easier for a user to select the date and time that they want.
When the element is submitted, it POSTs an ISO8601 / RFC 3339 string. Something like 2023-08-27T12:34
. This dramatically simplifies the back end code. That large complex function can now be reduced to either:
PHP
$dateTime = $post_data['dateTime'];
if ( strtotime($dateTime) == false ) {
...
}
or
PHP
$dateTime = DateTime::createFromFormat( "Y-m-d\TH:i", $post_data['dateTime'] );
if ( $dateTime == false ) {
...
}
I don't know if WordPress specifically needs to record the seconds something is scheduled for. If that is necessary, a random int can be zero padded and shoved on the end.
Performance
With something like this, you're always chasing marginal gains. Based on my very rough profiling, I expect the new function to be about twice as fast, albeit using about twice the memory. But we're talking fractions of seconds and hundreds of bytes.
Nevertheless, it all adds up!
It can't be that easy, right?
Well, probably not. There are several places where a date picker is used - so they'd all have to be changed.
I imagine there are several other things which expect to see jj, mm, dd etc posted. They'd either need to be updated, or a little front-end JS would have to be done.
And, as per the obligatory XKCD this will inevitably annoy someone.
But… it seems sensible, right? Use a native HTML control, a built-in PHP validator, and remove a bunch of custom code.
So, what do you think?
Neil says:
@edent says:
Neil says:
@edent says:
Neil says:
@edent says:
Sadly, this suggestion has been rejected. See https://core.trac.wordpress.org/ticket/61652#comment:8
More comments on Mastodon.