Data formats in dashboard

Not really important, but I recognized recently that the data format in the dashboard is … let’s say, a bit unsorted. I’m not sure whether it started with v2.3.0 or earlier.

Isn’t it in reverse order by date?

Actually it should be 29th, 27th, 18th, 3rd, and 11th. I had chosen the date formats j. F Y for dates and G:i for time, and German language, and everywhere else they are shown correctly. Only in the activity box on the dashboard dates are shown like that. That’s why I said it’s not important, it’s just not as it should be.

Oh, so the order IN the date format is BOTH garbled up AND incorrect (ie. the fallback is borked, too).

Lemme just check on an older install … Yeah, it must have come into place AFTER 2.0 - the old 2.0-based install that I got sitting here for testing purposes (client site) doesnt show this behaviour.

Might be using an incorrect / broken translation string?

cu, w0lf.

1 Like

Uses the function wp_dashboard_recent_posts found in wp-admin/includes/dashboard.php.

I compared both the 2.0 and the current 2.3.1 stable release, and the only difference is a notification / widget added for the CP plugin / theme directory. Everything else is identical - thus its almost certainly a translation string issue.

cu, w0lf.

1 Like

this all boils down to the translation tags being different from the original. What I mean is that basically when localizing a date format (since the destination might be very different from source) one has to replace the source tag with the destination tag, not just messing with the destination tag in the hopes it works. And that means having knowledge about those tags and date formats in PHP and it’s something that doesn’t easily come to mind to check. Also localization software does not like when you change the tag entirely and will throw an error (that localizer do need to ignore as exception). Some time this week I am going to see if it is possible to fix the issue by mass editing the tags in all the strings having it and eventually fix the thing.

2 Likes

This is the relevant PHP section from wp_dashboard_recent_posts:

if ( gmdate( 'Y-m-d', $time ) === $today ) {
				$relative = __( 'Today' );
			} elseif ( gmdate( 'Y-m-d', $time ) === $tomorrow ) {
				$relative = __( 'Tomorrow' );
			} elseif ( gmdate( 'Y', $time ) !== $year ) {
				/* translators: Date and time format for recent posts on the dashboard, from a different calendar year, see https://www.php.net/manual/datetime.format.php */
				$relative = date_i18n( __( 'M jS Y' ), $time );
			} else {
				/* translators: Date and time format for recent posts on the dashboard, see https://www.php.net/manual/datetime.format.php */
				$relative = date_i18n( __( 'M jS' ), $time );
			}

So its probably one of the last two if-clauses that are garbled up. The date_i18n function expects a date string.

Docs: date_i18n() – Function | Developer.WordPress.org

cu, w0lf.

yes, but the way crowdin (or any CAT tool work for that matter) is that they translate the date format to a tag and then express the tag as a string. so the issue is I think with the fact that when localizing to a foregn language with different format it does not get the right tag correctly converted.

in source the PHP sends the correct string (that to crowdin is a tag) and in the destination the localizer changes the tag format, and it being different messes up with the display since PHP expect it to match

2 Likes

Hm, I wonder if that tool has something like a “do not translate” marker. That’d probably fix the issue.

cu, w0lf.

It does. But this won’t fix. For a simple reason: Italian date format is different from en. This means if you don’t translate the en format will be left untouched in the destination resulting in dates showing as en strings.
What should happen is that php should detect the correct tag in destination and use the correct format…I am still on it because Crowdin should do the heavy lifting on that and not mess up. Something went wrong somewhere.

1 Like

Yeah, they claim that crowdin “supports” PHP. Looks like they’re just meaning “basics”, not important stuff like date formats. Which is kinda the ultra-basics.

Never trust a tool that promotes itself as “agile”. :woman_shrugging:

cu, w0lf.

Just an heads up about date formats.

ICU Message Syntax | Crowdin Docs according to this documentation I will have to make sure with each localizer that the correct ICU Message for the locale has been set for all the locale.

Apparently that is the issue at play here, that the ICU Message converting the date format to the one specified for the destination is set the wrong way.

1 Like

Well done for identifying the problem!

I have looked into this today after lurking in the i18n meeting, I believe the issue is in the German translation files ClassicPress serves.

The original English strings are PHP date / time parameters:

M - A short textual representation of a month (three letters)
j - The day of the month without leading zeros (1 to 31)
S - The English ordinal suffix for the day of the month (2 characters st, nd, rd or th. Works well with j)

In the core code “M jS Y” today would then display “5th Feb 2025”.

In the German translations the j and S are transposed, given that the description of S above states it is English I think it should probably just be removed.

@Matt yes, localizers SHOULD amend the tag they find in crowdin to reflect their locale. that however throws an error because Crowdin expects (like all the CAT Tools out there) the tag in source to correspond exactly with the one in destination.
this means the localizer first amend the tag, then approves as translated and then ignores the specific error thrown.

Ah, so it’s more that just removing the S but that would be a start right?

Consider that if you remove the ordinal all en_ locales won’t work.

The date format is CORRECT. And I double re-checked It is also rendering in Crowdin.

Correcting the date format has to be done by localizers when they reach a date. They align it with the way their country show them removing, adding, moving the array arguments.

The Crowdin throws an error (source not equal to destination) and they mass approve all strings with time formats they localized.

This tells the Crowdin that the change is needed to make the time format work.

Perhaps I am missing something here but let me work through my thoughts and findings so far.

The core source string for the affected strings are “M jS Y” and “M jS”, in English this will display “Feb 6th 2025” and “Feb 6th”.

In the German translation files, ClassicPress is being told to use “Sj m Y” and “M Sj” as the translation. This would display as “th06 02 2025” and “Feb th6” respectively. That already seems incorrect to me. My proposal is to remove English ordinal format parameter from the translation in the German files. So, use “j m Y” and “M j” as the translations - there is still a discrepancy between “m” and “M” (upper and lower case) but that is perhaps a more minor issue.

@MattyRob you do not need to change German locale SOURCE strings.

What I am saying is THAT is a job for the localizers.

A translator reaches a DATE (or a TAG what so ever) and they need to REWRITE the tag in DESTINATION with the correct formatting for THEIR LOCALE. After that they click translated and APPROVE THE STRING ignoring the warning that the SOURCE TAG and DESTINATION TAG are different because they are meant to be different for certain locales like en_EN and de_DE for example.

The tag is something Crowdin knows not to localize (so it remain static and the same between source and destination) because it is up to translators to determine the right format they want for it in destination. changing it in destination during the translation won’t affect source, only destination - so the locale used as source will continue to work.

EDITED TO ADD: our source is the en_EN version of strings, that localizers see to the LEFT of the screen. Destination is the translated content that they see to the right. source needs to remain the same, destination has to be changed on a per locale basis.
To do that one simple thing is change the tags as they meet them and tell Crowdin to ignore the specific warning that alerts destination is differing from source for that specific kind of tag. (it’s like an exclude this kind of warning rule in a way)