-
Notifications
You must be signed in to change notification settings - Fork 4.2k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
@wordpress/date: Fix ordinal token (S), RFC2822 token (r), and timezone offset handling #39670
Conversation
Size Change: +66 B (0%) Total Size: 1.21 MB
ℹ️ View Unchanged
|
// Does moment already have a locale with the right name? | ||
if ( momentLib.locales().includes( dateSettings.l10n.locale ) ) { | ||
// Is that locale misconfigured, e.g. because we are on a site running | ||
// WordPress < 6.0? |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Noting to myself that I need to submit a Core patch that makes this same fix there. Should also add a comment here to delete this code when the minimum WP version is 6.0.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks great, really appreciate all the tests that have been added.
What?
Fixes three bugs in
@wordpress/date
including #15221.wp.date.dateI18n( 'jS' )
should output e.g.23rd
, but it was outputting23
.wp.date.dateI18n( 'r' )
should be in English (per RFC822 spec) when site language is set to a non-English language.wp.date.format( 'P' )
should be'+00:00'
when site's timezone offset is'0'
.I've also added unit tests for all of the format string characters that
date
and its friends accept.The fix for #15221 was my intention. The other two bugs I noticed while writing unit tests.
Why?
WordPress doesn't have enough information about the current locale to translate a date's ordinal, which is why
wp_date( 'jS' )
in PHP always outputs e.g.23rd
in English even if the site's language is a non-English language.wp.date.date()
should match the behaviour ofwp_date()
so I did not attempt to fix this. (I have ideas on how we could...)Because there isn't any information about the ordinal, we don't set
ordinal
when defining our locale in Moment.js. This means that when Moment.js renders thejS
token, it will look at the parent locale for information on how to output the ordinal.Gutenberg is passing
parentLocale
tomoment.updateLocale()
, but this does not work. Onlymoment.defineLocale()
acceptsparentLocale
.We were naively translating the
r
token toddd, DD MMM YYYY HH:mm:ss ZZ
but that's not right as the day and month shouldn't be localised.moment.utcOffset()
accepts a string like'+00:00'
or an integer like0
. A string like'0'
is invalid and will cause the created moment instance to be in whatever timezone the user is in.How?
The fix is to use
defineLocale()
instead ofupdateLocale()
.Because Core might have already defined the locale, we must delete any existing locale before creating it. We can detect whether it's a locale created by Core or not based on whether it's incorrectly configured. Core (and Gutenberg, until this PR) is setting
LTS
,L
andLLLL
tonull
in the locale config, which is not permitted, according to the type definitions.Calling
locale( 'en' )
on the moment instance before rendering it will ensure it's in English.Coercing the site's timezone offset to a number before passing it to
utcOffset
will ensure Moment.js is happy.Testing Instructions
Unit tests are included. You could also follow the steps in #15221 and #39569.
You could also set your site to a few different languages and make sure dates e.g. in the Publish dropdown look correct.
I ordered the commits in a TDD way so you can
git checkout HEAD^
if you want to see that the new tests I added fail ontrunk
.