From 0587ca803fe8ce7c8cbf2769e8904ffbc67a0e58 Mon Sep 17 00:00:00 2001 From: web-orbit12 <115070295+web-orbit12@users.noreply.github.com> Date: Sun, 27 Sep 2026 10:47:52 +0400 Subject: [PATCH] fix(date): compute %U and %W week numbers like strftime (#958) --- src/util/strftime.spec.ts | 16 ++++++++++++++++ src/util/strftime.ts | 9 +++------ 2 files changed, 19 insertions(+), 6 deletions(-) diff --git a/src/util/strftime.spec.ts b/src/util/strftime.spec.ts index bacefce51..04082e7cc 100644 --- a/src/util/strftime.spec.ts +++ b/src/util/strftime.spec.ts @@ -140,6 +140,22 @@ describe('util/strftime', function () { it('should format %W as week of year, starts with 1', function () { expect(t(now, '%W')).toBe('01') }) + it('should format %U and %W as 00 before the first Sunday/Monday', function () { + // 2021-01-01 is a Friday + expect(t(new TestDate('2021-01-01 12:00:00'), '%U %W')).toBe('00 00') + expect(t(new TestDate('2021-01-03 12:00:00'), '%U %W')).toBe('01 00') + expect(t(new TestDate('2021-01-04 12:00:00'), '%U %W')).toBe('01 01') + }) + it('should keep Sunday in the previous %W week', function () { + // 2000-01-02 is a Sunday + expect(t(new TestDate('2000-01-02 12:00:00'), '%W')).toBe('00') + expect(t(new TestDate('2000-01-09 12:00:00'), '%W')).toBe('01') + }) + it('should format %U and %W when January 1st is the start day', function () { + // 2006-01-01 is a Sunday, 2007-01-01 is a Monday + expect(t(new TestDate('2006-07-05 12:00:00'), '%U %W')).toBe('27 27') + expect(t(new TestDate('2007-01-01 12:00:00'), '%U %W')).toBe('00 01') + }) }) describe('Time zone', () => { diff --git a/src/util/strftime.ts b/src/util/strftime.ts index cfbcd5811..2ebe2c4f5 100644 --- a/src/util/strftime.ts +++ b/src/util/strftime.ts @@ -23,12 +23,9 @@ function getDayOfYear (d: LiquidDate) { return num + d.getDate() } function getWeekOfYear (d: LiquidDate, startDay: number) { - // Skip to startDay of this week - const now = getDayOfYear(d) + (startDay - d.getDay()) - // Find the first startDay of the year - const jan1 = new Date(d.getFullYear(), 0, 1) - const then = (7 - jan1.getDay() + startDay) - return String(Math.floor((now - then) / 7) + 1) + // Days before the first startDay of the year belong to week 0 + const daysSinceStartDay = (d.getDay() - startDay + 7) % 7 + return String(Math.floor((getDayOfYear(d) - 1 - daysSinceStartDay + 7) / 7)) } function isLeapYear (d: LiquidDate) { const year = d.getFullYear()