Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Improving correctness of the formatInTimeZone close to the DST threshold #247

Merged
merged 1 commit into from
Mar 9, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions docs/OptionsWithTZ.js
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@
* See [toDate]{@link https://date-fns.org/docs/toDate}
* @property {String} [timeZone=''] - used to specify the IANA time zone offset of a date String.
* Used by all functions that take String as Date-like argument.
* @property {Date|Number} [originalDate] - used to pick the correct IANA time zone of a date.
* Used by `format` function.
* @property {Locale} [locale=defaultLocale] - the locale object.
* Used by `formatDistance`, `formatDistanceStrict`, `format` and `parse`.
* See [Locale]{@link https://date-fns.org/docs/Locale}
Expand Down
3 changes: 2 additions & 1 deletion src/format/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -286,6 +286,7 @@ var tzFormattingTokensRegExp = /([xXOz]+)|''|'(''|[^'])+('|$)/g
* - Some of the local week-numbering year tokens (`YY`, `YYYY`) that are confused with the calendar year tokens
* (`yy`, `yyyy`). See: https://git.io/fxCyr
* @param {String} [options.timeZone=''] - used to specify the IANA time zone offset of a date String.
* @param {Date|Number} [options.originalDate] - used to pick the correct IANA time zone of a date.
* @returns {String} the formatted date string
* @throws {TypeError} 2 arguments required
* @throws {RangeError} `options.additionalDigits` must be 0, 1 or 2
Expand Down Expand Up @@ -320,7 +321,7 @@ export default function format(dirtyDate, dirtyFormatStr, dirtyOptions) {

var matches = formatStr.match(tzFormattingTokensRegExp)
if (matches) {
var date = toDate(dirtyDate, options)
var date = toDate(options.originalDate || dirtyDate, options)
// Work through each match and replace the tz token in the format string with the quoted
// formatted time zone so the remaining tokens can be filled in by date-fns#format.
formatStr = matches.reduce(function (result, token) {
Expand Down
1 change: 1 addition & 0 deletions src/format/index.js.flow
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ type OptionsWithTZ = {
firstWeekContainsDate?: 1 | 2 | 3 | 4 | 5 | 6 | 7,
additionalDigits?: 0 | 1 | 2,
timeZone?: string,
originalDate?: Date | number,
locale?: Locale,
includeSeconds?: boolean,
addSuffix?: boolean,
Expand Down
2 changes: 1 addition & 1 deletion src/format/test.js
Original file line number Diff line number Diff line change
Expand Up @@ -101,7 +101,7 @@ describe('format', function () {
assert(format(date, "''h 'o''clock'''") === "'5 o'clock'")
})

it('accepts new line charactor', function () {
it('accepts new line character', function () {
var date = new Date(2014, 3, 4, 5)
assert.equal(format(date, "yyyy-MM-dd'\n'HH:mm:ss"), '2014-04-04\n05:00:00')
})
Expand Down
1 change: 1 addition & 0 deletions src/formatInTimeZone/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -27,5 +27,6 @@ import utcToZonedTime from '../utcToZonedTime/index.js'
export default function formatInTimeZone(date, timeZone, formatStr, options) {
var extendedOptions = cloneObject(options)
extendedOptions.timeZone = timeZone
extendedOptions.originalDate = date
return format(utcToZonedTime(date, timeZone), formatStr, extendedOptions)
}
1 change: 1 addition & 0 deletions src/formatInTimeZone/index.js.flow
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ type OptionsWithTZ = {
firstWeekContainsDate?: 1 | 2 | 3 | 4 | 5 | 6 | 7,
additionalDigits?: 0 | 1 | 2,
timeZone?: string,
originalDate?: Date | number,
locale?: Locale,
includeSeconds?: boolean,
addSuffix?: boolean,
Expand Down
57 changes: 57 additions & 0 deletions src/formatInTimeZone/test.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import assert from 'power-assert'
import enGB from 'date-fns/locale/en-GB'
import formatInTimeZone from './index'

describe('formatInTimeZone', function () {
Expand Down Expand Up @@ -43,6 +44,62 @@ describe('formatInTimeZone', function () {
})
})

describe('populates the timezone name and offset correctly close to DST threshold', function () {
it('during summer time: CEST', function () {
var date = new Date('2021-08-01T00:30:00Z')
var timeZone = 'Europe/Paris'
var format = 'z XXX'
var expected = 'CEST +02:00'
var options = { locale: enGB }
assert(formatInTimeZone(date, timeZone, format, options) === expected)
})

it('during winter time: CET', function () {
var date = '2021-01-01T01:30:00Z'
var timeZone = 'Europe/Paris'
var format = 'z XXX'
var expected = 'CET +01:00'
var options = { locale: enGB }
assert(formatInTimeZone(date, timeZone, format, options) === expected)
})

it('before DST changeover: (CEST to CET)', function () {
var date = '2021-10-31T00:30:00Z'
var timeZone = 'Europe/Paris'
var format = 'z XXX'
var expected = 'CEST +02:00'
var options = { locale: enGB }
assert(formatInTimeZone(date, timeZone, format, options) === expected)
})

it('after DST changeover: (CEST to CET)', function () {
var date = '2021-10-31T01:30:00Z'
var timeZone = 'Europe/Paris'
var format = 'z XXX'
var expected = 'CET +01:00'
var options = { locale: enGB }
assert(formatInTimeZone(date, timeZone, format, options) === expected)
})

it('before DST changeover: (CET to CEST)', function () {
var date = '2021-03-28T00:30:00Z'
var timeZone = 'Europe/Paris'
var format = 'z XXX'
var expected = 'CET +01:00'
var options = { locale: enGB }
assert(formatInTimeZone(date, timeZone, format, options) === expected)
})

it('after DST changeover: (CET to CEST)', function () {
var date = '2021-03-28T01:30:00Z'
var timeZone = 'Europe/Paris'
var format = 'z XXX'
var expected = 'CEST +02:00'
var options = { locale: enGB }
assert(formatInTimeZone(date, timeZone, format, options) === expected)
})
})

it('throws a RangeError on invalid time zones', function () {
var date = '1986-04-04T10:32:55.123Z'
assert.throws(
Expand Down
1 change: 1 addition & 0 deletions src/fp/format/index.js.flow
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ type OptionsWithTZ = {
firstWeekContainsDate?: 1 | 2 | 3 | 4 | 5 | 6 | 7,
additionalDigits?: 0 | 1 | 2,
timeZone?: string,
originalDate?: Date | number,
locale?: Locale,
includeSeconds?: boolean,
addSuffix?: boolean,
Expand Down
1 change: 1 addition & 0 deletions src/fp/formatInTimeZone/index.js.flow
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ type OptionsWithTZ = {
firstWeekContainsDate?: 1 | 2 | 3 | 4 | 5 | 6 | 7,
additionalDigits?: 0 | 1 | 2,
timeZone?: string,
originalDate?: Date | number,
locale?: Locale,
includeSeconds?: boolean,
addSuffix?: boolean,
Expand Down
1 change: 1 addition & 0 deletions src/fp/formatInTimeZoneWithOptions/index.js.flow
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ type OptionsWithTZ = {
firstWeekContainsDate?: 1 | 2 | 3 | 4 | 5 | 6 | 7,
additionalDigits?: 0 | 1 | 2,
timeZone?: string,
originalDate?: Date | number,
locale?: Locale,
includeSeconds?: boolean,
addSuffix?: boolean,
Expand Down
1 change: 1 addition & 0 deletions src/fp/formatWithOptions/index.js.flow
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ type OptionsWithTZ = {
firstWeekContainsDate?: 1 | 2 | 3 | 4 | 5 | 6 | 7,
additionalDigits?: 0 | 1 | 2,
timeZone?: string,
originalDate?: Date | number,
locale?: Locale,
includeSeconds?: boolean,
addSuffix?: boolean,
Expand Down
1 change: 1 addition & 0 deletions src/fp/getTimezoneOffset/index.js.flow
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ type OptionsWithTZ = {
firstWeekContainsDate?: 1 | 2 | 3 | 4 | 5 | 6 | 7,
additionalDigits?: 0 | 1 | 2,
timeZone?: string,
originalDate?: Date | number,
locale?: Locale,
includeSeconds?: boolean,
addSuffix?: boolean,
Expand Down
1 change: 1 addition & 0 deletions src/fp/index.js.flow
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ type OptionsWithTZ = {
firstWeekContainsDate?: 1 | 2 | 3 | 4 | 5 | 6 | 7,
additionalDigits?: 0 | 1 | 2,
timeZone?: string,
originalDate?: Date | number,
locale?: Locale,
includeSeconds?: boolean,
addSuffix?: boolean,
Expand Down
1 change: 1 addition & 0 deletions src/fp/toDate/index.js.flow
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ type OptionsWithTZ = {
firstWeekContainsDate?: 1 | 2 | 3 | 4 | 5 | 6 | 7,
additionalDigits?: 0 | 1 | 2,
timeZone?: string,
originalDate?: Date | number,
locale?: Locale,
includeSeconds?: boolean,
addSuffix?: boolean,
Expand Down
1 change: 1 addition & 0 deletions src/fp/toDateWithOptions/index.js.flow
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ type OptionsWithTZ = {
firstWeekContainsDate?: 1 | 2 | 3 | 4 | 5 | 6 | 7,
additionalDigits?: 0 | 1 | 2,
timeZone?: string,
originalDate?: Date | number,
locale?: Locale,
includeSeconds?: boolean,
addSuffix?: boolean,
Expand Down
1 change: 1 addition & 0 deletions src/fp/utcToZonedTime/index.js.flow
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ type OptionsWithTZ = {
firstWeekContainsDate?: 1 | 2 | 3 | 4 | 5 | 6 | 7,
additionalDigits?: 0 | 1 | 2,
timeZone?: string,
originalDate?: Date | number,
locale?: Locale,
includeSeconds?: boolean,
addSuffix?: boolean,
Expand Down
1 change: 1 addition & 0 deletions src/fp/utcToZonedTimeWithOptions/index.js.flow
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ type OptionsWithTZ = {
firstWeekContainsDate?: 1 | 2 | 3 | 4 | 5 | 6 | 7,
additionalDigits?: 0 | 1 | 2,
timeZone?: string,
originalDate?: Date | number,
locale?: Locale,
includeSeconds?: boolean,
addSuffix?: boolean,
Expand Down
1 change: 1 addition & 0 deletions src/fp/zonedTimeToUtc/index.js.flow
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ type OptionsWithTZ = {
firstWeekContainsDate?: 1 | 2 | 3 | 4 | 5 | 6 | 7,
additionalDigits?: 0 | 1 | 2,
timeZone?: string,
originalDate?: Date | number,
locale?: Locale,
includeSeconds?: boolean,
addSuffix?: boolean,
Expand Down
1 change: 1 addition & 0 deletions src/fp/zonedTimeToUtcWithOptions/index.js.flow
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ type OptionsWithTZ = {
firstWeekContainsDate?: 1 | 2 | 3 | 4 | 5 | 6 | 7,
additionalDigits?: 0 | 1 | 2,
timeZone?: string,
originalDate?: Date | number,
locale?: Locale,
includeSeconds?: boolean,
addSuffix?: boolean,
Expand Down
1 change: 1 addition & 0 deletions src/getTimezoneOffset/index.js.flow
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ type OptionsWithTZ = {
firstWeekContainsDate?: 1 | 2 | 3 | 4 | 5 | 6 | 7,
additionalDigits?: 0 | 1 | 2,
timeZone?: string,
originalDate?: Date | number,
locale?: Locale,
includeSeconds?: boolean,
addSuffix?: boolean,
Expand Down
1 change: 1 addition & 0 deletions src/index.js.flow
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ type OptionsWithTZ = {
firstWeekContainsDate?: 1 | 2 | 3 | 4 | 5 | 6 | 7,
additionalDigits?: 0 | 1 | 2,
timeZone?: string,
originalDate?: Date | number,
locale?: Locale,
includeSeconds?: boolean,
addSuffix?: boolean,
Expand Down
1 change: 1 addition & 0 deletions src/toDate/index.js.flow
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ type OptionsWithTZ = {
firstWeekContainsDate?: 1 | 2 | 3 | 4 | 5 | 6 | 7,
additionalDigits?: 0 | 1 | 2,
timeZone?: string,
originalDate?: Date | number,
locale?: Locale,
includeSeconds?: boolean,
addSuffix?: boolean,
Expand Down
1 change: 1 addition & 0 deletions src/utcToZonedTime/index.js.flow
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ type OptionsWithTZ = {
firstWeekContainsDate?: 1 | 2 | 3 | 4 | 5 | 6 | 7,
additionalDigits?: 0 | 1 | 2,
timeZone?: string,
originalDate?: Date | number,
locale?: Locale,
includeSeconds?: boolean,
addSuffix?: boolean,
Expand Down
1 change: 1 addition & 0 deletions src/zonedTimeToUtc/index.js.flow
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ type OptionsWithTZ = {
firstWeekContainsDate?: 1 | 2 | 3 | 4 | 5 | 6 | 7,
additionalDigits?: 0 | 1 | 2,
timeZone?: string,
originalDate?: Date | number,
locale?: Locale,
includeSeconds?: boolean,
addSuffix?: boolean,
Expand Down
1 change: 1 addition & 0 deletions typings.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ declare module 'date-fns-tz' {
firstWeekContainsDate?: 1 | 2 | 3 | 4 | 5 | 6 | 7
additionalDigits?: 0 | 1 | 2
timeZone?: string
originalDate?: Date | number
locale?: Locale
includeSeconds?: boolean
addSuffix?: boolean
Expand Down