diff --git a/src/util/liquid-date.ts b/src/util/liquid-date.ts index 655b2bfadf..d3d141f6d5 100644 --- a/src/util/liquid-date.ts +++ b/src/util/liquid-date.ts @@ -3,7 +3,11 @@ import { isString } from './underscore' // one minute in milliseconds const OneMinute = 60000 -const ISO8601_TIMEZONE_PATTERN = /([zZ]|([+-])(\d{2}):(\d{2}))$/ +/** + * Need support both ISO8601 and RFC2822 as in major browsers & NodeJS + * RFC2822: https://datatracker.ietf.org/doc/html/rfc2822#section-3.3 + */ +const TIMEZONE_PATTERN = /([zZ]|([+-])(\d{2}):?(\d{2}))$/ const monthNames = [ 'January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December' @@ -126,7 +130,7 @@ export class LiquidDate { * Given that a template is expected to be parsed fewer times than rendered. */ static createDateFixedToTimezone (dateString: string, locale: string): LiquidDate { - const m = dateString.match(ISO8601_TIMEZONE_PATTERN) + const m = dateString.match(TIMEZONE_PATTERN) // representing a UTC timestamp if (m && m[1] === 'Z') { return new LiquidDate(+new Date(dateString), locale, 0) diff --git a/test/integration/filters/date.spec.ts b/test/integration/filters/date.spec.ts index 8c1d6ee371..294d48dc0e 100644 --- a/test/integration/filters/date.spec.ts +++ b/test/integration/filters/date.spec.ts @@ -80,19 +80,23 @@ describe('filters/date', function () { return test('{{ "1991-02-22T00:00:00" | date: "%Y-%m-%dT%H:%M:%S"}}', '1991-02-22T00:00:00') }) describe('when preserveTimezones is enabled', function () { - const opts: LiquidOptions = { preserveTimezones: true } + const opts: LiquidOptions = { preserveTimezones: true, locale: 'en-US' } it('should not change the timezone between input and output', function () { return test('{{ "1990-12-31T23:00:00Z" | date: "%Y-%m-%dT%H:%M:%S"}}', '1990-12-31T23:00:00', undefined, opts) }) it('should apply numeric timezone offset (0)', function () { - return test('{{ "1990-12-31T23:00:00+00:00" | date: "%Y-%m-%dT%H:%M:%S"}}', '1990-12-31T23:00:00', undefined, opts) + return test('{{ "1990-12-31T23:00:00+00:00" | date: "%Y-%m-%dT%H:%M:%S %z"}}', '1990-12-31T23:00:00 +0000', undefined, opts) }) it('should apply numeric timezone offset (-1)', function () { - return test('{{ "1990-12-31T23:00:00-01:00" | date: "%Y-%m-%dT%H:%M:%S"}}', '1990-12-31T23:00:00', undefined, opts) + return test('{{ "1990-12-31T23:00:00-01:00" | date: "%Y-%m-%dT%H:%M:%S %z"}}', '1990-12-31T23:00:00 -0100', undefined, opts) }) it('should apply numeric timezone offset (+2.30)', function () { - return test('{{ "1990-12-31T23:00:00+02:30" | date: "%Y-%m-%dT%H:%M:%S"}}', '1990-12-31T23:00:00', undefined, opts) + return test('{{ "1990-12-31T23:00:00+02:30" | date: "%Y-%m-%dT%H:%M:%S %z"}}', '1990-12-31T23:00:00 +0230', undefined, opts) + }) + it('should support timezone in more casual JavaScript Date', async () => { + await test('{{ "2025-01-02 03:04:05 -0100" | date: "%Y-%m-%dT%H:%M:%S %z" }}', '2025-01-02T03:04:05 -0100', undefined, opts) + await test('{{ "2025-01-02 03:04:05 -0100" | date }}', 'Thursday, January 2, 2025 at 3:04 am -0100', undefined, opts) }) it('should automatically work when timezone not specified', function () { return test('{{ "1990-12-31T23:00:00" | date: "%Y-%m-%dT%H:%M:%S"}}', '1990-12-31T23:00:00', undefined, opts)