Skip to content

Extract localeDateFormat helper from timeago utils

Lukas Eipert requested to merge leipert-refactor-locale-datetime-utils into master

What does this MR do and why?

Extract localeDateFormat helper from timeago utils

The timeago utils are currently housing some wrappers around Intl.DateTimeFormat which are used if the user opts to see absolute Dates everywhere.

This MR extracts the logic into a new singleton, which has not a single, but a ton of features:

  1. It respects the users locale preference
  2. It respects the users preference for hourCycle (AM/PM vs 24h)
  3. All the formatters are lazy-loaded upon first use, because it is rather expensive to create a formatter, but fast to use one.
  4. It exposes a well-documented, limited set of formatters, so that developers have an easier time to choose the correct formatter.
  5. If needbe the lazy-loaded getters can be reset (tests, or maybe on the User preference page, where we could show a live preview how the dates look.
  6. All available formatters are also exposed as string constants, so that we have an easier time if certain Vue components want to pass a format as a prop.
  7. Each formatter exposes a format and a formatRange function to format single dates and date ranges, respectively.
  8. Both those functions accept "Dateish" values, so anything which could be used to create a date. This is mainly for backwards compatibility with the existing dateFormat function

Currently only two date formatters are available:

  1. localDateFormat.asDateTime. Prints a medium sized date and time with minute precision.
  2. localDateFormat.asDate. Prints a medium sized date.

It's deliberate that only these formatters are available now, more are going to follow, as we slowly migrate from other APIs to this one.

Other features that aren't available yet:

  1. formatting dates as iso-like dates (yyyy-mm-dd)
  2. formatting dates in different timezones from the user or UTC

The reason these aren't available: We have to look how to expose these options while also keeping the API surface reasonable.

In the end, this new API is meant to replace:

  1. formatDate, as this function is not locale aware
  2. Date.prototype.toLocaleDateString and Date.prototype.toLocaleString, as those APIs are about 22x slower.
  3. Custom instantiations of Intl.DateTimeFormat. As this might be slower, but also result in sub-optimal User experience, because the formats chosen could be conflicting with the user expectations, by e.g. forcing 12h/24h formats.

See also: gitlab-org/frontend/rfcs#90

Screenshots or screen recordings

N/A – No user visible changes, but for developers the JSDoc have a nice preview:

What JetBrains IDE (RubyMine) VSCode
Auto Complete rubymine-auto-complete vscode-auto-complete
Docs on localDateFormat rubymine-localdatetime vscode-localdatetime
Docs on localDateFormat.asDateTime rubymine-as-datetime vscode-as-datetime
Docs on localDateFormat.asDate rubymine-as-date vscode-as-date

How to set up and validate locally

  1. Start the GDK
  2. Set your time settings to "absolute".
  3. Go to any page (eg. repo, commits) with a lot of dates. The absolute rendered dates should still be there.

MR acceptance checklist

This checklist encourages us to confirm any changes have been analyzed to reduce risks in quality, performance, reliability, security, and maintainability.

Edited by Lukas Eipert

Merge request reports

Loading