{"id":13553477,"url":"https://github.com/marnusw/date-fns-tz","last_synced_at":"2025-05-13T16:06:25.890Z","repository":{"id":38454718,"uuid":"151880553","full_name":"marnusw/date-fns-tz","owner":"marnusw","description":"Complementary library for date-fns v2 adding IANA time zone support","archived":false,"fork":false,"pushed_at":"2024-12-31T22:43:48.000Z","size":5829,"stargazers_count":1117,"open_issues_count":72,"forks_count":120,"subscribers_count":5,"default_branch":"master","last_synced_at":"2025-04-16T23:40:09.740Z","etag":null,"topics":["date","date-fns","iana","javascript","time","timezone","utilities","zone-formatting","zone-helpers"],"latest_commit_sha":null,"homepage":"","language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/marnusw.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE.md","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2018-10-06T20:50:29.000Z","updated_at":"2025-04-09T20:29:09.000Z","dependencies_parsed_at":"2024-06-18T11:21:37.081Z","dependency_job_id":"deca4a5e-fabb-40b0-a218-94cd90cd81bf","html_url":"https://github.com/marnusw/date-fns-tz","commit_stats":{"total_commits":231,"total_committers":47,"mean_commits":4.914893617021277,"dds":"0.34199134199134196","last_synced_commit":"b882090f6571d8cad53e1b707d9a62af4345b27a"},"previous_names":[],"tags_count":51,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/marnusw%2Fdate-fns-tz","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/marnusw%2Fdate-fns-tz/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/marnusw%2Fdate-fns-tz/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/marnusw%2Fdate-fns-tz/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/marnusw","download_url":"https://codeload.github.com/marnusw/date-fns-tz/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":249334003,"owners_count":21252921,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["date","date-fns","iana","javascript","time","timezone","utilities","zone-formatting","zone-helpers"],"created_at":"2024-08-01T12:02:25.926Z","updated_at":"2025-04-23T20:42:30.417Z","avatar_url":"https://github.com/marnusw.png","language":"JavaScript","funding_links":["https://www.buymeacoffee.com/marnusw"],"categories":["JavaScript","📅 Date \u0026 Time"],"sub_categories":["E2E Testing"],"readme":"# date-fns-tz\n\nTime zone support for [date-fns](https://date-fns.org/) v3.0.0 using the\n[Intl API](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Intl).\nBy using the browser API no time zone data needs to be included in code bundles. Modern browsers\nand Node.js all support the\n[necessary features](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/DateTimeFormat#Browser_compatibility),\nand for those that don't a [polyfill](https://formatjs.io/docs/polyfills/intl-datetimeformat) can be used.\n\nIf you do not wish to use a polyfill the time zones can still be specified as offsets\nsuch as '-0200' or '+04:00', but not IANA time zone names.\n\n**Note:** `date-fns` is a peer dependency of this library.\n\nIf you find this library useful, why not\n\n\u003ca href=\"https://www.buymeacoffee.com/marnusw\" target=\"_blank\"\u003e\u003cimg src=\"https://www.buymeacoffee.com/assets/img/custom_images/orange_img.png\" alt=\"Buy Me A Coffee\" style=\"height: 41px !important;width: 174px !important;box-shadow: 0px 3px 2px 0px rgba(190, 190, 190, 0.5) !important;-webkit-box-shadow: 0px 3px 2px 0px rgba(190, 190, 190, 0.5) !important;\" \u003e\u003c/a\u003e\n\n## ESM and CommonJS\n\nThis library supports CommonJS and native ESM imports. The exports field in [package.json](./package.json)\ndefines the correct entry point depending on project type, so the same import path is used for both.\nMake sure to set the `type` property in your project's `package.json` to either `module`, for ESM, or `commonjs`.\n\nEven when using ESM some CommonJS imports from `date-fns` will be used until they support\nESM natively as well [date-fns#1781](https://github.com/date-fns/date-fns/issues/1781).\nThis is because an ESM project cannot use ESM imports from a library that doesn't specify\n`{\"type\": \"module\"}`.\n\n## Table of Contents\n\n- [Overview](#overview)\n- [Date and time zone formatting](#date-and-time-zone-formatting)\n  - [`formatInTimeZone`](#formatintimezone) - Formats a date in the provided time zone,\n    regardless of the system time zone\n- [Time zone offset helpers](#time-zone-offset-helpers)\n  - [`fromZonedTime`](#fromzonedtime) - Given a date and any time zone, returns a `Date` with the equivalent UTC time\n  - [`toZonedTime`](#tozonedtime) - Get a date/time representing local time in a given time zone from the UTC date\n  - [`getTimezoneOffset`](#gettimezoneoffset) - Gets the offset in milliseconds between the time zone and UTC time\n- [Low-level formatting helpers](#low-level-formatting-helpers)\n  - [`format`](#format) - Extends `date-fns/format` with support for all time zone tokens,\n    including `z..zzzz`\n  - [`toDate`](#todate) - Can be used to parse a `Date` from a date string representing time in\n    any time zone\n- [Usage with Android](#usage-with-android)\n\n## Overview\n\nWorking with UTC or ISO date strings is easy, and so is working with JS dates when all times\nare displayed in a user's local time in the browser. The difficulty comes when working with another\ntime zone's local time, one other than the current system's, like on a Node server or when showing\nthe time of an event in a specific time zone, like an event in LA at 8pm PST regardless of where\na user resides.\n\nIn this case there are two relevant pieces of information:\n\n- a fixed moment in time in the form of a timestamp, UTC or ISO date string, and\n- the time zone descriptor, usually an offset or IANA time zone name (e.g. `America/New_York`).\n\nLibraries like Moment and Luxon, which provide their own date-time classes, manage these\ntimestamp and time zone values internally. Since `date-fns` always returns a plain JS Date,\nwhich implicitly has the current system's time zone, helper functions are provided for handling\ncommon time zone related use cases.\n\n## Date and time zone formatting\n\n### `formatInTimeZone`\n\nThis function takes a `Date` instance in the system's local time or an ISO8601 string, and\nan IANA time zone name or offset string. It then formats this date in the target time zone\nregardless of the system's local time zone.\n\nIt supports the same format tokens as `date-fns/format`, and adds full support for:\n\n- The `z..zzz` Unicode tokens: _short specific non-location format_, e.g. `EST`\n- The `zzzz` Unicode token: _long specific non-location format_, e.g. `Eastern Standard Time`\n\nUnlike `date-fns/format`, the `z..zzzz`, `x..xxxxx`, `X..XXXXX` and `O..OOO` tokens will all\nprint the formatted value of the provided time zone rather than the system time zone.\n\nAn invalid date or time zone input will result in an `Invalid Date` passed to `date-fns/format`,\nwhich will throw a `RangeError`.\n\nFor most use cases this is the only function from this library you will need.\n\n```javascript\nimport { formatInTimeZone } from 'date-fns-tz'\n\nconst date = new Date('2014-10-25T10:46:20Z')\n\nformatInTimeZone(date, 'America/New_York', 'yyyy-MM-dd HH:mm:ssXXX') // 2014-10-25 06:46:20-04:00\nformatInTimeZone(date, 'America/New_York', 'yyyy-MM-dd HH:mm:ss zzz') // 2014-10-25 06:46:20 EST\nformatInTimeZone(date, 'Europe/Paris', 'yyyy-MM-dd HH:mm:ss zzz') // 2014-10-25 12:46:20 GMT+2\n\n// The time zone name is generated by the Intl API which works best when a locale is also provided\nimport { enGB } from 'date-fns/locale/en-GB'\n\nformatInTimeZone(parisDate, 'Europe/Paris', 'yyyy-MM-dd HH:mm:ss zzz', { locale: enGB })\n// 2014-10-25 10:46:20 CEST\n\nformatInTimeZone(parisDate, 'Europe/Paris', 'yyyy-MM-dd HH:mm:ss zzzz', { locale: enGB })\n// 2014-10-25 10:46:20 Central European Summer Time\n```\n\n## Time zone offset helpers\n\nThese functions are useful when you are not formatting a date yourself, but passing it to\nthird-party code such as a date picker library alongside an input for selecting a time zone.\n\nTo discuss the usage of the time zone helpers let's assume we're writing a system where\nadministrators set up events which will start at a specific time in the venue's local time, and\nthis local time should be shown when accessing the site from anywhere in the world.\n\n### `fromZonedTime`\n\nGiven a date and any time zone, returns the equivalent `Date` in the current system time zone\nand the equivalent UTC time internally. An invalid date string or time zone will result in\nan `Invalid Date`.\n\n```ts\nfromZonedTime(date: Date|Number|String, timeZone: String): Date\n```\n\nSay a user is asked to input the date/time and time zone of an event. A date/time picker will\ntypically return a Date instance with the chosen date, in the user's local time zone, and a\nselect input might provide the actual IANA time zone name.\n\nIn order to work with this info effectively it is necessary to find the equivalent UTC time:\n\n```javascript\nimport { fromZonedTime } from 'date-fns-tz'\n\nconst date = getDatePickerValue() // e.g. 2014-06-25 10:00:00 (picked in any time zone)\nconst timeZone = getTimeZoneValue() // e.g. America/Los_Angeles\n\nconst utcDate = fromZonedTime(date, timeZone) // In June 10am in Los Angeles is 5pm UTC\n\npostToServer(utcDate.toISOString(), timeZone) // post 2014-06-25T17:00:00.000Z, America/Los_Angeles\n```\n\n### `toZonedTime`\n\nReturns a `Date` which will format as the local time of any time zone from a specific UTC time\nor date in the current system time zone. An invalid date string or time zone will result in\nan `Invalid Date`.\n\n```js\ntoZonedTime(date: Date|Number|String, timeZone: String): Date\n```\n\nSay the server provided a UTC date/time and a time zone which should be used as initial values\nfor the above form. The date/time picker will take a Date input which will be in the user's\nlocal time zone, but the date value must be that of the target time zone.\n\n```javascript\nimport { toZonedTime } from 'date-fns-tz'\n\nconst { isoDate, timeZone } = fetchInitialValues() // 2014-06-25T10:00:00.000Z, America/New_York\n\nconst date = toZonedTime(isoDate, timeZone) // In June 10am UTC is 6am in New York (-04:00)\n\nrenderDatePicker(date) // 2014-06-25 06:00:00 (in the system time zone)\nrenderTimeZoneSelect(timeZone) // America/New_York\n```\n\n### `getTimezoneOffset`\n\nReturns the offset in milliseconds between the time zone and UTC time.\n\n```js\ngetTimezoneOffset(timeZone: String, date: Date|Number): number\n```\n\nReturns the time zone offset from UTC time in milliseconds for IANA time zones as well\nas other time zone offset string formats.\n\nFor time zones where daylight savings time is applicable a `Date` should be passed on\nthe second parameter to ensure the offset correctly accounts for DST at that time of\nyear. When omitted, the current date is used.\n\nFor invalid time zones, `NaN` is returned.\n\n```javascript\nimport { getTimezoneOffset } from 'date-fns-tz'\n\nconst result = getTimezoneOffset('-07:00')\n//=\u003e -18000000 (-7 * 60 * 60 * 1000)\nconst result = getTimezoneOffset('Africa/Johannesburg')\n//=\u003e 7200000 (2 * 60 * 60 * 1000)\nconst result = getTimezoneOffset('America/New_York', new Date(2016, 0, 1))\n//=\u003e -18000000 (-5 * 60 * 60 * 1000)\nconst result = getTimezoneOffset('America/New_York', new Date(2016, 6, 1))\n//=\u003e -14400000 (-4 * 60 * 60 * 1000)\n```\n\n## Low-level formatting helpers\n\n### `format`\n\nThe `format` function exported from this library is used under the hood by `formatInTimeZone`\nand extends `date-fns/format` with full time zone support for:\n\n- The `z..zzz` Unicode tokens: _short specific non-location format_\n- The `zzzz` Unicode token: _long specific non-location format_\n\nWhen using those tokens with `date-fns/format` it falls back to the GMT time zone format, and\nalways uses the current system's local time zone. For example `zzz` in New York will always return\n`GMT-4` instead of the desired `EST`, and `zzz` in Paris `GMT+2` instead of `CEST`, making the\ntime zone tokens somewhat irrelevant. This extended `format` function returns the proper\nspecific non-location format, e.g. `EST` or `Eastern Standard Time`, and that of the target time\nzone (if provided, see below) rather than the system time zone.\n\nSince a JavaScript `Date` instance cannot convey the time zone information to the `format` function\nit is necessary to pass the `timeZone` value as an option on the third argument of `format`.\n\nSimilar to `date-fns/format`, when an invalid date is used a `RangeError` is thrown. When an invalid\ntime zone is provided _and included in the output_, i.e. with time zone tokens in the format\nstring, it will also throw a `RangeError`.\n\nTo format a date showing time for a specific time zone other than the system time zone, the\n`format` function can be combined with `toZonedTime`. This is what `formatInTimeZone` does\ninternally. _To clarify, the `format` function will never change the underlying date, it must be\nchanged to a zoned time before passing it to `format`._\n\nIn most cases there is no need to use `format` rather than `formatInTimeZone`. The only time\nthis makes sense is when `toZonedTime` has been applied to a date once, and you want to\nformat it multiple times to different outputs.\n\n```javascript\nimport { format, toZonedTime } from 'date-fns-tz'\n\nconst date = new Date('2014-10-25T10:46:20Z')\n\nconst nyDate = toZonedTime(date, 'America/New_York')\nconst parisDate = toZonedTime(date, 'Europe/Paris')\n\nformat(nyDate, 'yyyy-MM-dd HH:mm:ssXXX', { timeZone: 'America/New_York' }) // 2014-10-25 06:46:20-04:00\nformat(nyDate, 'yyyy-MM-dd HH:mm:ss zzz', { timeZone: 'America/New_York' }) // 2014-10-25 06:46:20 EST\nformat(parisDate, 'yyyy-MM-dd HH:mm:ss zzz', { timeZone: 'Europe/Paris' }) // 2014-10-25 10:46:20 GMT+2\n\n// The time zone name is generated by the Intl API which works best when a locale is also provided\nimport { enGB } from 'date-fns/locale/en-GB'\n\nformat(parisDate, 'yyyy-MM-dd HH:mm:ss zzz', {\n  timeZone: 'Europe/Paris',\n  locale: enGB,\n})\n// 2014-10-25 10:46:20 CEST\nformat(parisDate, 'yyyy-MM-dd HH:mm:ss zzzz', {\n  timeZone: 'Europe/Paris',\n  locale: enGB,\n})\n// 2014-10-25 10:46:20 Central European Summer Time\n```\n\n### `toDate`\n\nThe `toDate` function can be used to parse a `Date` from a string containing a date and time\nrepresenting time in any time zone by providing an IANA time zone name on the `timeZone` option.\n\nAn invalid date string or time zone will result in an `Invalid Date`.\n\n```javascript\nimport { toDate, format } from 'date-fns-tz'\n\n// Offsets in the date string work as usual and take precedence\nconst parsedDate = toDate('2014-10-25T13:46:20+04:00')\nconst parisDate = toZonedTime(parsedDate, 'Europe/Paris')\nformat(parisDate, 'yyyy-MM-dd HH:mm:ssxxx', { timeZone: 'Europe/Paris' }) // 2014-10-25 11:46:20+02:00\n\n// Since toDate simply clones a Date instance, the timeZone option is effectively ignored in this case\nconst date = new Date('2014-10-25T13:46:20Z')\nconst clonedDate = toDate(date, { timeZone: 'Europe/Paris' })\nassert(date.valueOf() === clonedDate.valueOf())\n\n// When there is no offset in the date string the timeZone property is used\nconst parsedDate = toDate('2014-10-25T13:46:20', { timeZone: 'Asia/Bangkok' })\nconst bangkokDate = toZonedTime(parsedDate, 'Asia/Bangkok')\nformat(bangkokDate, 'yyyy-MM-dd HH:mm:ssxxx', { timeZone: 'Asia/Bangkok' }) // 2014-10-25 13:46:20+07:00\n```\n\n## Usage with Android\n\nThis library works with React Native on iOS, and on Android with Hermes which supports\n`Intl` by default.\n\nIn Android projects that do not use Hermes, make this change in `android/app/build.gradle`:\n\n```diff\n- def jscFlavor = 'org.webkit:android-jsc:+'\n+ def jscFlavor = 'org.webkit:android-jsc-intl:+'\n```\n\n## Usage with Node.js\n\nNode.js supports the `Intl` API and ships with full ICU data included in the binary since v13,\nso this library works by default.\n\n## Credit\n\nThe idea of using the Intl API for time zone support was inspired by the [Luxon](https://github.com/moment/luxon)\nlibrary.\n\nThe initial port of the idea into date-fns was done by [@benmccan](https://github.com/benmccann) in\n[date-fns/#676](https://github.com/date-fns/date-fns/pull/676).\n\n## License\n\nMIT © Marnus Weststrate\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmarnusw%2Fdate-fns-tz","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fmarnusw%2Fdate-fns-tz","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmarnusw%2Fdate-fns-tz/lists"}