From e68514f0667c958b578d580d11482ae881d7b803 Mon Sep 17 00:00:00 2001 From: KBS Date: Wed, 30 Sep 2026 01:47:25 +0900 Subject: [PATCH] fix(date): compute %C and %y from the numeric year (#961) Both were sliced from the year string, so years with other than four digits gave the wrong century and two-digit year, and %y was a string that the - and _ flags could not unpad. Compute them arithmetically and pad them to two digits, matching Ruby's strftime. --- src/util/strftime.spec.ts | 8 ++++++++ src/util/strftime.ts | 8 +++++--- 2 files changed, 13 insertions(+), 3 deletions(-) diff --git a/src/util/strftime.spec.ts b/src/util/strftime.spec.ts index 04082e7cc..af8b242f2 100644 --- a/src/util/strftime.spec.ts +++ b/src/util/strftime.spec.ts @@ -18,6 +18,14 @@ describe('util/strftime', function () { it('should format %y as 2-digit year', function () { expect(t(now, '%y')).toBe('16') }) + it('should format %C and %y from the numeric year', function () { + const year999 = new TestDate('0999-06-15 00:00:00') + expect(t(year999, '%C')).toBe('09') + expect(t(year999, '%y')).toBe('99') + const year2005 = new TestDate('2005-06-15 00:00:00') + expect(t(year2005, '%y')).toBe('05') + expect(t(year2005, '%-y')).toBe('5') + }) describe('%j', function () { it('should format %j as day of year', function () { expect(t(then, '%j')).toBe('066') diff --git a/src/util/strftime.ts b/src/util/strftime.ts index 2ebe2c4f5..5725ccbca 100644 --- a/src/util/strftime.ts +++ b/src/util/strftime.ts @@ -43,11 +43,12 @@ function ordinal (d: LiquidDate) { } } function century (d: LiquidDate) { - return parseInt(d.getFullYear().toString().substring(0, 2), 10) + return Math.floor(d.getFullYear() / 100) } // default to 0 const padWidths: Record = { + C: 2, d: 2, e: 2, H: 2, @@ -60,7 +61,8 @@ const padWidths: Record = { M: 2, S: 2, U: 2, - W: 2 + W: 2, + y: 2 } const padSpaceChars = new Set('aAbBceklpP') @@ -110,7 +112,7 @@ const formatCodes: Record = { W: (d: LiquidDate) => getWeekOfYear(d, 1), x: (d: LiquidDate) => d.toLocaleDateString(), X: (d: LiquidDate) => d.toLocaleTimeString(), - y: (d: LiquidDate) => d.getFullYear().toString().slice(2, 4), + y: (d: LiquidDate) => (d.getFullYear() % 100 + 100) % 100, Y: (d: LiquidDate) => d.getFullYear(), z: getTimezoneOffset, Z: (d: LiquidDate, opts: FormatOptions) => d.getTimeZoneName() || getTimezoneOffset(d, opts),