Globalization Service
npm install @microsoft/globeProvides localization services for Electron and the browser.
Respects the OS date and time format configuration.
npm i@microsoft/globe
``typescript
import { TimeStringFormat, DateTimeFormatOptions, DateTimeFormatter } from 'globe';
// Instantiate the formatter
const dateTimeFormatter = new DateTimeFormatter(locale: string | ILocaleInfo);
`
locale is either a locale string (e.g.: en-US) or ILocaleInfo instance:
`typescript
type ILocaleInfo = {
// Supported platform
platform: "windows" | "macos";
// OS date & time format settings (see below for OS support)
regionalFormat: string; // e.g.: 'en-US'
shortDate: string; // e.g.: 'dd/MM/y'
longDate: string; // e.g.: 'd MMMM y'
fullDate: string; // e.g.: 'EEEE d MMMM y'
shortTime: string; // e.g.: 'HH:mm'
};
`
To format a date and time value:
`typescript`
/**
* Localize the date/time
* @param date The date/time to localize
* @param format The format to be used for the localization
* @returns The localized date/time string
*/
function formatDateTime(date: number | Date, format: DateTimeFormatOptions) {
return dateTimeFormatter.formatDateTime(date, format);
}
The function throws in case an unexpected OS date and time format string is
provided! Most likely this will happen if you feed it the OS strings verbatim and
the OS is configured with a custom date/time format string. If you don't desire
this behavior, you can choose your own fallback (and telemetry) by wrapping the
call to Globe and redoing it without OS-honoring support in case it fails with
the _Unexpected format string_ error.
Globe is able to honor OS system date and time formatting settings, but it does
not do OS detection and date and time settings querying out of the box as these
features depend on the context you're using Globe in.
If you want to take an advantage of this feature, we recommend you follow this
pattern:
- Make window.getLocaleInfoAsync available (return Promise)DateTimeFormatter
- Cache the result of that function and provide it in the getLocaleInfoAsync
constructor
- Use the exported alias function if you prefer, whichwindow.getLocaleInfoAsync
wraps the function for you:
`typescript | 'macos' /);
import { getLocaleInfoAsync } from "@microsoft/globe";
// Provide the supported platform name and obtain the OS locale settings
const localeInfo = await getLocaleInfoAsync(/ 'windows
new DateTimeFormatter(localeInfo);
``
#### Windows
The values provided can be found in Date & Time this way:
- Click on the date and time in the taskbar
- Click on Adjust date and time
- Click on Region & language (here you see the values formatted)
- Click on Advanced
- Check the values of short date, long date and short time

#### macOS
- Click on the date and time in the menubar
- Click on Open date and time preferences
- Click on Date and time
- Click on Oppen language and region
- Click on Advanced
- Click on Dates
- Check the values of short and long

- Click on Times
- Check the value of

MacOS format patterns reference
`sh`
npm install
npm run build
Build the package first: npm run build.
npm test
There is a GitHub Actions workflow which runs the
tests on every push to any branch.
NPM releases are automated through Azure DevOps pipeline.
1. Create a change file:
`sh`
yarn change
This creates a change file in the /change directory documenting your changes.
2. Bump the version:
`sh`
yarn bump
This uses Beachball to update the version in package.json and generate the changelog.
3. Commit and push:
`sh`
git add .
git commit -m "Release: Bump version to x.x.x"
git push origin master
4. Automatic publishing:
- The Azure DevOps pipeline detects the version change
- Builds, signs, and publishes the package to npm automatically
- Only publishes if the version has been bumped
Add new format MEDIUM_DATE_SHORT_TIME
Attempting to fix VDI issues on Electron
Fixed 12 hours format for Windows
Use for loops in an attempt to reduce memory consumption
Use reducers in an attempt to reduce memory consumption (eliminate anonymous functions)
Better checks for cases where time zone is not provided by default
Use hourCycle for mac as it is supported in Electron 8
Mac full date format
Support quotes in format
Support K and k tokens for mac
Removed SHORT_DATE_TIME_NO_YEAR
Add new format SHORT_DATE_TIME_NO_YEAR
Add getLocaleInfoAsync to module export
Improve error logging for unknown formats
Avoid depending on Intl.DateTimeFormatParts which is not available in es5
SafeDateTimeFormat with fallback to UTC if timezone is not detected or provided
Use 0 instead of 24 for H and HH tokens
Precompute formats so that applying is faster.
Added FULL, FULL_WITH_YEAR, FULL_TIME, LONG_TIME_WITH_TIMEZONE, LONG_WITH_TIMEZONE, LONG_WITH_YEAR_TIMEZONE, SHORT and SHORT_WITH_YEAR formats.
Do not use for...of because of perf impact.
Improved performance, by adding more caching.
Fixed a bug in Windows AM/PM token detection in the OS formatting string.
Instead for looking for either t or tt, Globe was only looking for tt.
Fixed typo in seconds in long date and time format.
Added formatting rules for:
- Long date and time
- Long weekday and long time
- Long weekday and short time
- Short weekday and long time
- Short weekday and short time
Fixed an issue where Windows OS format string was treated as if it was a
macOS format string.
We've added preliminary handling for AM/PM (day period) format which
supports the HOUR_ONLY option when using the OS date and time format strings.HOUR_ONLY
The supported OSs (macOS and Windows) do not expose a dedicated format string
for an hour-only scenario, so we detect whether the OS format string for
short date includes the AM/PM format string token and constuct a makeshift format string for that case which either also includes AM/PM or
doesn't depending on if the original short time format string did.
We've switched to a single-level cache between the pair made up by the locale
and the format options stringified and the DateTimeFormat Intl instance.
Previously the cache was two-level, a map for the locale (string) and a weak
map for the format options (object), which had the same performance, but was
more complex and needlessly so, because JSON.stringify is so fast being native
code, the overhead has actually decreased when using it for the cache key.
The access pattern of Globe is now such that the first call to formatDateundefined
given an format options object (or ) takes about 20ms, which is
the cost of initializing and caching the Intl.DateTimeFormat instance and
subsequent calls are practically equivalent in speed to raw Intl, meaning
they take <1ms.
Add missing key coercion which caused the locale+format cache to have no effect
in case no format was provided.
Caching internal Intl.DateTimeFormat instances keyed by the given locale and
format object.
Added HOUR_ONLY pattern.
Added few more date time formatting patterns, like Medium and Full dates and times.
Refactored the DateTimeFormatter constructor to accept either a localeILocaleInfo
string or an instance of and added information and supportILocaleInfo
for obtaining through OS settings.
Release a version with the release notes in the readme.
- Fixed a typo in the file name in the module field of package.json@microsoft
- Fixed installation instructions to use the current scope -
- Fixed the usage sample and clean up the readme a bit
Initial release of the code pulled out of a larger codebase for
public consumption.
Right now the tests are too rudimentary and are in JavaScript. Doing this will make it
easier, faster and less error-prone to test the library.
We're in a process of redesigning the OS-formatting portion of this library and will
publish a design documentation first and an implementation PR second when we're ready
to invest more resources into improving this.
This will be useful when attempting to catch this exact error. Right now we only throw
this error so barring programming errors any error that can possibly be caught is this
one, but it will be better to provide prototype equality (e instanceof OSDateTimeError`)
to be able to catch more selectively and confidently.
Contributions are welcome (see the CONTRIBUTING file),
though please keep in mind the work-in-progress proof-of-concept state.
Might make sense to just observe/discuss until the thing gets stable and well-documented.
This project is licensed under the MIT License, see the LICENSE file for details.