feat: timezone name for opts.timezoneOffset and date argument, fixes #553

This commit is contained in:
Harttle
2022-11-30 00:20:12 +08:00
committed by Harttle
parent b7ab357964
commit 89c6c7676d
3 changed files with 30 additions and 7 deletions
+14 -4
View File
@@ -1,7 +1,7 @@
import { toValue, stringify, isString, isNumber, TimezoneDate, LiquidDate, strftime } from '../util'
import { FilterImpl } from '../template'
export function date (this: FilterImpl, v: string | Date, format: string, timeZoneOffset?: number) {
export function date (this: FilterImpl, v: string | Date, format: string, timezoneOffset?: number | string) {
const opts = this.context.opts
let date: LiquidDate
v = toValue(v)
@@ -22,10 +22,10 @@ export function date (this: FilterImpl, v: string | Date, format: string, timeZo
date = v
}
if (!isValidDate(date)) return v
if (timeZoneOffset !== undefined) {
date = new TimezoneDate(date, timeZoneOffset)
if (timezoneOffset !== undefined) {
date = new TimezoneDate(date, parseTimezoneOffset(date, timezoneOffset))
} else if (opts.timezoneOffset !== undefined) {
date = new TimezoneDate(date, opts.timezoneOffset!)
date = new TimezoneDate(date, parseTimezoneOffset(date, opts.timezoneOffset))
}
return strftime(date, format)
}
@@ -33,3 +33,13 @@ export function date (this: FilterImpl, v: string | Date, format: string, timeZo
function isValidDate (date: any): date is Date {
return (date instanceof Date || date instanceof TimezoneDate) && !isNaN(date.getTime())
}
/**
* need pass in a `date` because offset is dependent on whether DST is active
*/
function parseTimezoneOffset (date: Date, timeZone: string | number) {
if (isNumber(timeZone)) return timeZone
const utcDate = new Date(date.toLocaleString('en-US', { timeZone: 'UTC' }))
const tzDate = new Date(date.toLocaleString('en-US', { timeZone }))
return (utcDate.getTime() - tzDate.getTime()) / 6e4
}
+2 -2
View File
@@ -35,8 +35,8 @@ export interface LiquidOptions {
ownPropertyOnly?: boolean;
/** Modifies the behavior of `strictVariables`. If set, a single undefined variable will *not* cause an exception in the context of the `if`/`elsif`/`unless` tag and the `default` filter. Instead, it will evaluate to `false` and `null`, respectively. Irrelevant if `strictVariables` is not set. Defaults to `false`. **/
lenientIf?: boolean;
/** JavaScript timezoneOffset for `date` filter, default to local time. That means if you're in Australia (UTC+10), it'll default to -600 */
timezoneOffset?: number;
/** JavaScript timezone name or timezoneOffset for `date` filter, default to local time. That means if you're in Australia (UTC+10), it'll default to `-600` or `Australia/Lindeman` */
timezoneOffset?: number | string;
/** Strip blank characters (including ` `, `\t`, and `\r`) from the right of tags (`{% %}`) until `\n` (inclusive). Defaults to `false`. */
trimTagRight?: boolean;
/** Similar to `trimTagRight`, whereas the `\n` is exclusive. Defaults to `false`. See Whitespace Control for details. */
+14 -1
View File
@@ -64,16 +64,29 @@ describe('filters/date', function () {
it('should support timezone offset argument', function () {
return test('{{ "1990-12-31T23:00:00Z" | date: "%Y-%m-%dT%H:%M:%S", 360}}', '1990-12-31T17:00:00')
})
it('should support timezone name argument', function () {
return test('{{ "1990-12-31T23:00:00Z" | date: "%Y-%m-%dT%H:%M:%S", "Asia/Colombo" }}', '1991-01-01T04:30:00')
})
it('should support timezone name argument when DST is not active', function () {
return test('{{ "2021-01-01T23:00:00Z" | date: "%Y-%m-%dT%H:%M:%S", "America/New_York" }}', '2021-01-01T18:00:00')
})
it('should support timezone name argument when DST is active', function () {
return test('{{ "2021-06-01T23:00:00Z" | date: "%Y-%m-%dT%H:%M:%S", "America/New_York" }}', '2021-06-01T19:00:00')
})
it('should offset date literal with timezone 00:00 specified', function () {
return test('{{ "1990-12-31T23:00:00+00:00" | date: "%Y-%m-%dT%H:%M:%S"}}', '1990-12-31T17:00:00', undefined, opts)
})
it('should offset date literal with timezone -01:00 specified', function () {
return test('{{ "1990-12-31T23:00:00-01:00" | date: "%Y-%m-%dT%H:%M:%S"}}', '1990-12-31T18:00:00', undefined, opts)
})
it('should offset date from scope', function () {
it('should offset date from scope (timezone offset)', function () {
const scope = { date: new Date('1990-12-31T23:00:00Z') }
return test('{{ date | date: "%Y-%m-%dT%H:%M:%S"}}', scope, '1990-12-31T17:00:00', opts)
})
it('should offset date from scope (timezone name)', function () {
const scope = { date: new Date('1990-12-31T23:00:00Z') }
return test('{{ date | date: "%Y-%m-%dT%H:%M:%S"}}', scope, '1990-12-31T17:00:00', { timezoneOffset: 'America/Merida' })
})
it('should reflect timezoneOffset', function () {
const scope = { date: new Date('1990-12-31T23:00:00Z') }
return test('{{ date | date: "%z"}}', scope, '-0600', opts)