A lightweight polyfill for Temporal, successor to the JavaScript Date
object.
Only 20.0 kB, with near-perfect spec compliance.
- Installation
- Comparison with
@js-temporal/polyfill
- Spec Compliance
- Browser Support
- BigInt Considerations
- Tree-shakeable API (coming soon)
npm install temporal-polyfill
Import as an ES module without side effects:
import { Temporal } from 'temporal-polyfill'
console.log(Temporal.Now.zonedDateTimeISO().toString())
Or, import globally:
import 'temporal-polyfill/global'
console.log(Temporal.Now.zonedDateTimeISO().toString())
Use a <script>
tags with a CDN link:
<script src='https://cdn.jsdelivr.net/npm/[email protected]/global.min.js'></script>
<script>
console.log(Temporal.Now.zonedDateTimeISO().toString())
</script>
Package |
temporal-polyfill
|
@js-temporal/polyfill
|
Repo | fullcalendar/temporal-polyfill | js-temporal/temporal-polyfill |
Creators | FullCalendar lead dev arshaw | Champions of the Temporal proposal |
Minified+gzip size ✝ | 20.0 kB | 43.2 kB (+116%) |
Minified-only size ✝ | 58.7 kB | 206.0 kB (+251%) |
Spec compliance |
Strict compliance for common API. Relaxed compliance for subclassing built-in types. |
Strict compliance for entire API. |
Spec date | Nov 2023 (latest) | May 2023 |
BigInt Approach | Internally avoids BigInt operations altogether | Internally relies on JSBI |
Global usage in ESM |
import 'temporal-polyfill/global'
|
Not currently possible |
✝ Compares global.min.js with index.esm.js, which are similarly transpiled.
All calendar systems (ex: chinese
, persian
) and time zones are supported.
Compliance with the latest version of the Temporal spec (Nov 2023) is near-perfect with the following intentional deviations:
Duration::toString
does not display units greater thanNumber.MAX_SAFE_INTEGER
according to spec. Precision is chosen differently.- Custom implementations of Calendars and TimeZones are queried differently. Only affects those subclassing built-in classes, which is extremely rare. See the CALLING entries in the test-ignore file.
- There are believed to be 3 bugs in the Temporal spec itself, one of which has been filed. See SPEC-BUG entries in the test-ignore file.
- Canonicalization of time zone IDs is simplified, leveraging the built-in
Intl
API. Intl.DateTimeFormat
has not been polyfilled to accept number-offset values for thetimeZone
option.- Method descriptors and
Function::length
are not strictly compliant due to ES-related space-saving techniques.
The Official ECMAScript Conformance Test Suite has:
- 6811 total Temporal-related test files
- 6138 passed by
temporal-polyfill
- 495 ignored due to superficial method descriptor compliance
- 178 ignored due to other aforementioned intentional deviations
Minimum required browsers: | |||||
Chrome 60 (Jul 2017) |
Firefox 55 (Aug 2017) |
Safari 11.1 (Mar 2018) |
Safari iOS 11.3 (Mar 2018) |
Edge 79 (Jan 2020) |
Node.js 14 (Apr 2020) |
If you transpile, you can support older browsers down to: |
|||||
Chrome 57 (Mar 2017) |
Firefox 52 (Mar 2017) |
Safari 10 (Sep 2016) |
Safari iOS 10 (Sep 2016) |
Edge 15 (Apr 2017) |
Node.js 14 (Apr 2020) |
This polyfill works fine in environments that do not support BigInt.
However, to use methods that accept/emit them, your browser must support BigInt.
Here's how to sidestep this browser compatibility issue:
❌ Avoid microseconds/nanoseconds | ✅ Use milliseconds instead |
---|---|
instant.epochMicroseconds |
instant.epochMilliseconds |
instant.epochNanoseconds |
instant.epochMilliseconds |
Temporal.Instant.fromEpochMicroseconds(micro) |
Temporal.Instant.fromEpochMilliseconds(milli) |
Temporal.Instant.fromEpochNanoseconds(nano) |
Temporal.Instant.fromEpochMilliseconds(milli) |
new Temporal.Instant(nano) |
Temporal.Instant.fromEpochMilliseconds(milli) |
zonedDateTime.epochMicroseconds |
zonedDateTime.epochMilliseconds |
zonedDateTime.epochNanoseconds |
zonedDateTime.epochMilliseconds |
new Temporal.ZonedDateTime(nano, tz, cal)
|
Temporal.Instant.fromEpochMilliseconds(milli) .toZonedDateTimeISO() // or toZonedDateTime
|
🚧 Coming Soon
For library authors and other devs who are hyper-concerned about bundle size, temporal-polyfill
will be providing an alternate API designed for tree-shaking.
import * as ZonedDateTime from 'temporal-polyfill/fns/zoneddatetime'
const zdt = ZonedDateTime.from({ year: 2024, month: 1, day: 1 })
const s = ZonedDateTime.toString(zdt) // not how you normally call a method!