Skip to content

Instantly share code, notes, and snippets.

@fpintos
Last active September 29, 2021 17:47
Show Gist options
  • Save fpintos/4960209a66e4602d72514d647004e4ad to your computer and use it in GitHub Desktop.
Save fpintos/4960209a66e4602d72514d647004e4ad to your computer and use it in GitHub Desktop.
OWA Format Strings

dateTimeFormats.json

These localized strings allows owa-datetime to handle languages that require special formatting when showing individual parts of a date.

DateFormat and TimeFormat Settings

The date and time formats in the user's settings provide several pieces of information about how dates should be formatted.

For example:

  • we get the relative position of the date parts to one another
  • we know if we need to use leading zeros or not
  • we know if hours should be shown using 12- or 24-hours
  • we know if we should display months using numbers or names
  • and when showing month names, if their should be abbreviated or not.

However, these settings do not carry information about special cases that should be taken into account when displaying individual parts of a date.

For example:

  • In some languages, a standalone day or year requires extra characters around the number.
  • When showing the week day with the date or time (or both) in some languages the week day comes before the date, while in others it comes at the end or in between the date and the time. And some languages put extra characters around the week day name.

The information about these special cases is not present in the user settings.

Design differences between OwaDateTime and owa-datetime

In jsMVVM these special cases were handled with hardcoded tables in LocaleSpecific. OwaDateTime would then consult those tables during CultureFormat, based on the user's culture. Not every format allowed for customization. Strings were concatenated with their order driven by such hardcoded tables. Adding a new language with special cases required making changes to the formatting code and the hardcoded tables.

In owa-datetime, we use localized strings in all formatting functions to go from the format specifiers found in the user's settings to a localized one and to perform any kind of concatenation of the individual date parts. All languages, with and without special cases, are handled with the same code path. Adding a language that contains special cases requires only new localized strings. Localizers will have control of how individual date parts are formatted.

When the user changes culture, these formatting strings are reloaded like every other localized string in the product and affected React components re-render.

From user settings to the localized format

Formatting functions such as formatDay extract the raw format specifier from the user date or time format settings. This raw format specifier is then used to lookup a localized format. The default case is for a format specifiers to be mapped to itself. However, languages with special requirements return a custom format string.

For example:

  • Suppose a user running with yyyy-MM-dd as the selected date format.
  • When formatUserDate is called we respect the user's setting and the date January 2 2017 will return 2017-01-02.
  • When formatting the same date with formatDay, owa-datetime extracts 'dd' as the raw format specifier from the date format settings and uses that to lookup the localized format.
    • In the default case the localized format is also dd, and we get back 02.
    • But in a language like Japanese, the localized format is d日, and we get back 2日.

Which format specifiers require overrides and in which languages?

Unicode CLDR and its JSON repository can provide a number of these overrides.

Be aware that localization in Microsoft products does not adopt CLDR data verbatim. For details, see this article and these guidelines.

Others might be obtained from System.Globalization.DateTimeFormatInfo.

Others are specific to OWA.

Ultimately, localizers proficient in a particular language are responsible for providing the correct overrides.

Supported Format Specifiers

These are the format specifiers that can appear in the localized strings:

Mask Description
d The day of the month, from 1 through 31.
dd The day of the month, from 01 through 31.
ddd The abbreviated name of the day of the week.
dddd The full name of the day of the week.
M The month, from 1 through 12.
MM The month, from 01 through 12.
MMM The abbreviated name of the month.
MMMM The full name of the month.
yy The year, from 00 to 99.
yyyy The year as a four-digit number.
h The hour, using a 12-hour clock from 1 to 12.
hh The hour, using a 12-hour clock from 01 to 12.
H The hour, using a 24-hour clock from 0 to 23.
HH The hour, using a 24-hour clock from 00 to 23.
m The minute, from 0 through 59.
mm The minute, from 00 through 59.
s The second, from 0 through 59.
ss The second, from 00 through 59.
t The uppercase AM/PM designator, abbreviated.
tt The uppercase AM/PM designator.
T The lowercase AM/PM designator, abbreviated.
TT The lowercase AM/PM designator.
'...' Literal string delimiter.

These are a subset of the format specifiers used by .NET.

Unlike .NET, a single-character format specifier must not be prefixed by space or % in OWA. In other words, map d to d, not %d.

The t, tt, T and TT look inverted in terms of uppercase/lowercase and this is by design. Windows and .NET use tt for uppercase AM/PM, so we had to go with TT for lowercase. :-(

Resource strings that combine format specifiers

When OWA formats a date string, it start by getting the localized versions of d, dd, M, MM, MMM, MMMM, yy, yyyy and so on, and then combines them with the localized version of the following resources:

dayWeekDayFormat
monthDayFormatDayFirst
monthDayFormatMonthFirst
monthDayWeekDayFormatDayFirst
monthDayWeekDayFormatMonthFirst
monthDayYearFormat
monthDayYearFormat
shortWeekDayMonthDayYearFormat
weekDayMonthDayFormat
weekDayMonthDayYearFormat
yearMonthFormatMonthFirst
yearMonthFormatYearFirst

These resources will use insertion parameters ({0}, {1}, etc) to define where the localized day/month/year will appear.

Optionally, localizers proficient in a particular language might simply hardcode the format specifiers into these resource strings.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment