Date & Time

Installation

A context and hook using the browser Intl.DateTimeFormat API that uses Procore's locale settings, preset options, and Procore specific formatting. Pseudo-localization is supported. If pseudo locale active the "literals", i.e. number seperators, will be rendered with dots instead of slashes (e.g. 12.2.2019 5.00 PM EST).

IE11 Requires Time Zone polyfill
Core React uses the brower's Intl DateTimeFormatAPIs in tandem with date-fns and date-fns-tz. In order to support IE11, client applications will require a polyfill to enable time zone features.
Time Zone Console Logging
Enable time zone console logging by setting the environment variable TZ_LOG to true. This can be used during development to compare inputs and outputs of date shifting.

To learn about date and time support in Core React, review the date, time, and time zones guide. See the DateTimeFormat browser API docs for more information on the global Intl.

Usage

Anything inside a DateTimeProvider with a timeZone set, will act as if it was in that time zone. While some providers typically have only one instance near the top of the tree like I18nProvider, a client could have several DateTimeProvider throughout based on data formats. This affects DateSelect and useDateTime. Please review more on the working time dates & time zones guide for how to opt-in/opt-out.

Given the providers set up like below:

The format func does time zone shifting if applicable. Calling new Date() when in context of a time zone will render the current time in the time zone. If the time zone is undefined, it will not shift but warning: if displaying the time, the label of the time zone will be the current users location which could be incorrect. More information on how Core uses the Intl.DateTimeFormat.

DateTimeProvider

Props

  • hour12: boolean
  • timeZone: string of IANA_timezone_names

useDateTime

format(Date, DateTimeFormat, Intl.DateTimeFormatOptions, Intl.DateTimeFormatOptions)

The first argument is a Date object.

Note: The maintainers of JavaScript officially discourage instantiating Date objects by passing a string to the Date constructor, for example Date.new('2018-12-07T03:24:00'), due to inconsistent and poorly documented browser behavior. For consistent and well documented parsing of datetime strings to Date objects, recommend using the parse method in date-fns or the toDate() method in moment.js. Core React recommends using date-fns over moment.js as the go-to date util library.

Preset Types

The second argument is a string that will result in Intl.DateTimeFormatOptions. The predefined strings accomplish the most common use cases. The pattern of the strings represent English format, e.g. weekday-date is Sunday, January 31, 2021, if we wanted that with time weekday-date-at-time is Sunday, January 31, 2021 at 2:30 PM PST. Design guidelines require displaying a time zone with time. There are two patterns to display a date with a time, ending with -at-time or starting with time-on-.

The presets of date and time formats include:

  • abbr-weekday-abbr-date
  • abbr-weekday-abbr-date-at-time
  • date
  • date-at-time
  • numeric-date
  • numeric-date-at-time
  • time
  • time-on-abbr-weekday-abbr-date
  • time-on-weekday-date
  • time-on-date
  • time-on-numeric-date
  • weekday-date
  • weekday-date-at-time
  • none

The third and fourth arguments are optional and each is an object of additional Intl date time format options. This will be merged with and override the default options. The former options are for date and the latter for time when using time-on- and -at-time. More on the options can be found in the DateTimeFormat API docs.

Examples

Date with weekday and time

24 hour clock

The default is undefined, which the browser will go by the locale convention.

Customize options

Note: The first options param for time-on- and -at-time variants is for date, the second is for time.

Locales

Display Formats

Locale: en

abbr-weekday-abbr-date:
abbr-weekday-abbr-date-at-time:
date:
date-at-time:
numeric-date:
numeric-date-at-time:
time:
time-on-abbr-weekday-abbr-date:
time-on-weekday-date:
time-on-date:
time-on-numeric-date:
weekday-date:
weekday-date-at-time:
none:


Locale: en-CA

abbr-weekday-abbr-date:
abbr-weekday-abbr-date-at-time:
date:
date-at-time:
numeric-date:
numeric-date-at-time:
time:
time-on-abbr-weekday-abbr-date:
time-on-weekday-date:
time-on-date:
time-on-numeric-date:
weekday-date:
weekday-date-at-time:
none:


Locale: fr-CA

abbr-weekday-abbr-date:
abbr-weekday-abbr-date-at-time:
date:
date-at-time:
numeric-date:
numeric-date-at-time:
time:
time-on-abbr-weekday-abbr-date:
time-on-weekday-date:
time-on-date:
time-on-numeric-date:
weekday-date:
weekday-date-at-time:
none:


Locale: fr-FR

abbr-weekday-abbr-date:
abbr-weekday-abbr-date-at-time:
date:
date-at-time:
numeric-date:
numeric-date-at-time:
time:
time-on-abbr-weekday-abbr-date:
time-on-weekday-date:
time-on-date:
time-on-numeric-date:
weekday-date:
weekday-date-at-time:
none:


Locale: es

abbr-weekday-abbr-date:
abbr-weekday-abbr-date-at-time:
date:
date-at-time:
numeric-date:
numeric-date-at-time:
time:
time-on-abbr-weekday-abbr-date:
time-on-weekday-date:
time-on-date:
time-on-numeric-date:
weekday-date:
weekday-date-at-time:
none:


Locale: en-AE

abbr-weekday-abbr-date:
abbr-weekday-abbr-date-at-time:
date:
date-at-time:
numeric-date:
numeric-date-at-time:
time:
time-on-abbr-weekday-abbr-date:
time-on-weekday-date:
time-on-date:
time-on-numeric-date:
weekday-date:
weekday-date-at-time:
none:


Locale: en-AU

abbr-weekday-abbr-date:
abbr-weekday-abbr-date-at-time:
date:
date-at-time:
numeric-date:
numeric-date-at-time:
time:
time-on-abbr-weekday-abbr-date:
time-on-weekday-date:
time-on-date:
time-on-numeric-date:
weekday-date:
weekday-date-at-time:
none:


Locale: en-GB

abbr-weekday-abbr-date:
abbr-weekday-abbr-date-at-time:
date:
date-at-time:
numeric-date:
numeric-date-at-time:
time:
time-on-abbr-weekday-abbr-date:
time-on-weekday-date:
time-on-date:
time-on-numeric-date:
weekday-date:
weekday-date-at-time:
none:


Locale: en-SG

abbr-weekday-abbr-date:
abbr-weekday-abbr-date-at-time:
date:
date-at-time:
numeric-date:
numeric-date-at-time:
time:
time-on-abbr-weekday-abbr-date:
time-on-weekday-date:
time-on-date:
time-on-numeric-date:
weekday-date:
weekday-date-at-time:
none:


Locale: ko

abbr-weekday-abbr-date:
abbr-weekday-abbr-date-at-time:
date:
date-at-time:
numeric-date:
numeric-date-at-time:
time:
time-on-abbr-weekday-abbr-date:
time-on-weekday-date:
time-on-date:
time-on-numeric-date:
weekday-date:
weekday-date-at-time:
none:


Locale: th-TH

abbr-weekday-abbr-date:
abbr-weekday-abbr-date-at-time:
date:
date-at-time:
numeric-date:
numeric-date-at-time:
time:
time-on-abbr-weekday-abbr-date:
time-on-weekday-date:
time-on-date:
time-on-numeric-date:
weekday-date:
weekday-date-at-time:
none:


Locale: pt

abbr-weekday-abbr-date:
abbr-weekday-abbr-date-at-time:
date:
date-at-time:
numeric-date:
numeric-date-at-time:
time:
time-on-abbr-weekday-abbr-date:
time-on-weekday-date:
time-on-date:
time-on-numeric-date:
weekday-date:
weekday-date-at-time:
none:


Locale: is-IS

abbr-weekday-abbr-date:
abbr-weekday-abbr-date-at-time:
date:
date-at-time:
numeric-date:
numeric-date-at-time:
time:
time-on-abbr-weekday-abbr-date:
time-on-weekday-date:
time-on-date:
time-on-numeric-date:
weekday-date:
weekday-date-at-time:
none:


Locale: de-DE

abbr-weekday-abbr-date:
abbr-weekday-abbr-date-at-time:
date:
date-at-time:
numeric-date:
numeric-date-at-time:
time:
time-on-abbr-weekday-abbr-date:
time-on-weekday-date:
time-on-date:
time-on-numeric-date:
weekday-date:
weekday-date-at-time:
none:


Locale: pseudo

abbr-weekday-abbr-date:
abbr-weekday-abbr-date-at-time:
date:
date-at-time:
numeric-date:
numeric-date-at-time:
time:
time-on-abbr-weekday-abbr-date:
time-on-weekday-date:
time-on-date:
time-on-numeric-date:
weekday-date:
weekday-date-at-time:
none: