date-fns-tz

repository·master·Indexed 22 days ago

https://github.com/marnusw/date-fns-tz

A utility library providing time zone support for date-fns v3 using the native Intl API. It enables formatting and conversion between UTC and specific time zones (IANA names or offsets) without large data bundles. Key functions include formatInTimeZone, fromZonedTime, toZonedTime, getTimezoneOffset, and toDate, with a dedicated functional programming (FP) API available via the date-fns-tz/fp entrypoint.

Tokens
8.2K
Snippets
33
Records
37
Agent score
76%

What's inside date-fns-tz

  1. Overview of date-fns-tz

    master

    date-fns-tz provides time zone support for date-fns v3.0.0 by leveraging the native browser Intl API. This approach avoids including large time zone data bundles in your code.

    Key details:

    • Compatibility: Works in modern browsers and Node.js. For older environments, use an Intl polyfill.
    • Time Zone Specification: You can use IANA time zone names (e.g., America/New_York) or offsets (e.g., -0200, +04:00). If a polyfill is not used, IANA names are not supported.
    • Peer Dependency: date-fns is a required peer dependency.
  2. Install and Import date-fns-tz

    master

    The library supports both CommonJS and native ESM imports. The exports field in package.json ensures the correct entry point is used based on your project type. Ensure your package.json has the type property set to either module (for ESM) or commonjs.

    Note: Even in ESM projects, some date-fns imports may resolve to CommonJS until date-fns provides native ESM support.

  3. Configure Android for time zone support

    master

    This library relies on the Intl API. It works out-of-the-box on iOS (React Native) and Android with Hermes.

    If your Android project does not use Hermes, you must ensure the Intl API is available by updating your android/app/build.gradle file to use the intl flavor of JSC:

    - def jscFlavor = 'org.webkit:android-jsc:+'
    + def jscFlavor = 'org.webkit:android-jsc-intl:+'
  4. Format time zone names with locales

    master

    Time zone names are generated via the Intl API. For the best results when using tokens like zzz or zzzz, provide a locale from date-fns/locale in the options object.

    import { format, toZonedTime } from 'date-fns-tz'
    import { enGB } from 'date-fns/locale/en-GB'
    
    const date = new Date('2014-10-25T10:46:20Z')
    const parisDate = toZonedTime(date, 'Europe/Paris')
    
    format(parisDate, 'yyyy-MM-dd HH:mm:ss zzzz', {
      timeZone: 'Europe/Paris',
      locale: enGB,
    })
    // 2014-10-25 10:46:20 Central European Summer Time
  5. Convert UTC to a zoned date with toZonedTime

    master

    Returns a Date object that, when formatted, represents the local time of the specified time zone from a given UTC time. This is useful when you have a UTC timestamp from a server but need to initialize a UI component (like a date picker) with the time as it appears in a specific target time zone.

    Signature: toZonedTime(date: Date|Number|String, timeZone: String): Date

    An invalid date string or time zone will result in an Invalid Date.

    import { toZonedTime } from 'date-fns-tz'
    
    const { isoDate, timeZone } = fetchInitialValues() // 2014-06-25T10:00:00.000Z, America/New_York
    
    const date = toZonedTime(isoDate, timeZone) // In June 10am UTC is 6am in New York (-04:00)
    
    renderDatePicker(date) // 2014-06-25 06:00:00 (in the system time zone)
    renderTimeZoneSelect(timeZone) // America/New_York
  6. Format a date in a specific time zone with formatInTimeZone

    master

    Use formatInTimeZone to format a Date instance or an ISO8601 string in a target time zone, regardless of the system's local time zone. It supports all standard date-fns/format tokens and adds support for time zone tokens:

    • z..zzz: Short specific non-location format (e.g., EST)
    • zzzz: Long specific non-location format (e.g., Eastern Standard Time)
    • x..xxxxx, X..XXXXX, O..OOO: Time zone offset tokens.

    Warning: An invalid date or time zone will result in an Invalid Date being passed to the formatter, which throws a RangeError.

    import { formatInTimeZone } from 'date-fns-tz'
    
    const date = new Date('2014-10-25T10:46:20Z')
    
    formatInTimeZone(date, 'America/New_York', 'yyyy-MM-dd HH:mm:ssXXX') // 2014-10-25 06:46:20-04:00
    formatInTimeZone(date, 'America/New_York', 'yyyy-MM-dd HH:mm:ss zzz') // 2014-10-25 06:46:20 EST
    formatInTimeZone(date, 'Europe/Paris', 'yyyy-MM-dd HH:mm:ss zzz') // 2014-10-25 12:46:20 GMT+2
    
    // Using a locale for better time zone name generation
    import { enGB } from 'date-fns/locale/en-GB'
    
    formatInTimeZone(date, 'Europe/Paris', 'yyyy-MM-dd HH:mm:ss zzz', { locale: enGB })
    // 2014-10-25 10:46:20 CEST
    
    formatInTimeZone(date, 'Europe/Paris', 'yyyy-MM-dd HH:mm:ss zzzz', { locale: enGB })
    // 2014-10-25 10:46:20 Central European Summer Time
  7. Get time zone offset in milliseconds with getTimezoneOffset

    master

    Returns the offset in milliseconds between the specified time zone and UTC.

    Signature: getTimezoneOffset(timeZone: String, date: Date|Number): number

    Usage Notes:

    • Supports IANA time zones and offset strings.
    • Daylight Savings Time (DST): For time zones where DST applies, pass a Date as the second parameter to ensure the offset is correct for that specific moment in time. If omitted, the current date is used.
    • Returns NaN for invalid time zones.
    import { getTimezoneOffset } from 'date-fns-tz'
    
    const result = getTimezoneOffset('-07:00')
    //=> -18000000 (-7 * 60 * 60 * 1000)
    
    const result = getTimezoneOffset('Africa/Johannesburg')
    //=> 7200000 (2 * 60 * 60 * 1000)
    
    // Accounting for DST in New York
    const result = getTimezoneOffset('America/New_York', new Date(2016, 0, 1)) // Jan (Standard Time)
    //=> -18000000 (-5 * 60 * 60 * 1000)
    
    const result = getTimezoneOffset('America/New_York', new Date(2016, 6, 1)) // June (Daylight Time)
    //=> -14400000 (-4 * 60 * 60 * 1000)
  8. Use the `format` function for time zone support

    master

    The format function extends date-fns/format by providing full time zone support for specific Unicode tokens: z..zzz (short specific non-location format) and zzzz (long specific non-location format).

    Unlike the standard date-fns/format, which falls back to GMT and uses the system's local time zone, this version returns the proper specific format (e.g., EST or Eastern Standard Time) for the target time zone.

    Important: Because a JavaScript Date instance cannot convey time zone information, you must pass the timeZone value in the third argument options object. To format a date for a specific time zone, you should combine format with toZonedTime (which is what formatInTimeZone does internally).

    import { format, toZonedTime } from 'date-fns-tz'
    
    const date = new Date('2014-10-25T10:46:20Z')
    const nyDate = toZonedTime(date, 'America/New_York')
    
    // You must provide the timeZone in the options object
    format(nyDate, 'yyyy-MM-dd HH:mm:ss zzz', { timeZone: 'America/New_York' }) // 2014-10-25 06:46:20 EST
  9. Convert a zoned date to UTC with fromZonedTime

    master

    Given a date and a time zone, fromZonedTime returns a Date object representing the equivalent UTC time. This is useful when receiving a local date/time from a user input (like a date picker) and needing to convert it to UTC for server storage.

    Signature: fromZonedTime(date: Date|Number|String, timeZone: String): Date

    An invalid date string or time zone will result in an Invalid Date.

    import { fromZonedTime } from 'date-fns-tz'
    
    const date = getDatePickerValue() // e.g. 2014-06-25 10:00:00 (picked in any time zone)
    const timeZone = getTimeZoneValue() // e.g. America/Los_Angeles
    
    const utcDate = fromZonedTime(date, timeZone) // In June 10am in Los Angeles is 5pm UTC
    
    postToServer(utcDate.toISOString(), timeZone) // post 2014-06-25T17:00:00.000Z, America/Los_Angeles
  10. Parse dates with `toDate`

    master

    The toDate function parses a string into a Date object. If the date string contains an offset (e.g., +04:00), that offset takes precedence. If the string lacks an offset, you can provide an IANA time zone name via the timeZone option to define the context of the date/time string.

    An invalid date string or time zone will result in an Invalid Date.

    import { toDate, toZonedTime, format } from 'date-fns-tz'
    
    // 1. Using offset in string (precedence over timeZone option)
    const parsedDate = toDate('2014-10-25T13:46:20+04:00')
    
    // 2. Using timeZone option when no offset is present in the string
    const bangkokDate = toDate('2014-10-25T13:46:20', { timeZone: 'Asia/Bangkok' })
    const zonedBangkok = toZonedTime(bangkokDate, 'Asia/Bangkok')
    format(zonedBangkok, 'yyyy-MM-dd HH:mm:ssxxx', { timeZone: 'Asia/Bangkok' }) // 2014-10-25 13:46:20+07:00
  11. Error handling in `toDate`

    master

    The toDate function may throw the following errors:

    • TypeError: Thrown if fewer than 1 argument is provided.
    • RangeError: Thrown if options.additionalDigits is not 0, 1, or 2.

    If the input is null or cannot be parsed into a valid date, the function returns an Invalid Date object (a Date instance where isNaN(date.getTime()) is true) rather than throwing.