fix(date): zero-pad milliseconds when formatting %N fractional seconds (#929)

%N renders the fractional part of the second. The milliseconds returned by
getMilliseconds() are the three most significant digits of that fraction and
must be zero-padded to three digits before use, otherwise sub-100ms values
lose their leading zeros:

  50ms => strftime("%N")  returned "500000000", expected "050000000"
   5ms => strftime("%3N") returned "500",       expected "005"

Pad the milliseconds to three digits before slicing to the requested width.
This commit is contained in:
spokodev
2026-07-09 23:16:44 +08:00
committed by GitHub
parent f9a1316d16
commit 2634f9de7b
2 changed files with 10 additions and 1 deletions
+9
View File
@@ -87,6 +87,15 @@ describe('util/strftime', function () {
expect(t(time, '%10N')).toBe('1290000000') expect(t(time, '%10N')).toBe('1290000000')
expect(t(time, '%0N')).toBe('129000000') expect(t(time, '%0N')).toBe('129000000')
}) })
it('should zero pad %N for sub-100ms fractional seconds', function () {
const time = new TestDate('2019-12-15 01:21:00.005')
expect(t(time, '%N')).toBe('005000000')
expect(t(time, '%3N')).toBe('005')
expect(t(time, '%6N')).toBe('005000')
const tens = new TestDate('2019-12-15 01:21:00.050')
expect(t(tens, '%N')).toBe('050000000')
expect(t(tens, '%2N')).toBe('05')
})
it('should format %p as upper cased am/pm', function () { it('should format %p as upper cased am/pm', function () {
expect(t(now, '%p')).toBe('PM') expect(t(now, '%p')).toBe('PM')
expect(t(then, '%p')).toBe('AM') expect(t(then, '%p')).toBe('AM')
+1 -1
View File
@@ -98,7 +98,7 @@ const formatCodes: Record<string, FormatCodeHandler> = {
M: (d: LiquidDate) => d.getMinutes(), M: (d: LiquidDate) => d.getMinutes(),
N: (d: LiquidDate, opts: FormatOptions) => { N: (d: LiquidDate, opts: FormatOptions) => {
const width = Number(opts.width) || 9 const width = Number(opts.width) || 9
const str = String(d.getMilliseconds()).slice(0, width) const str = padStart(String(d.getMilliseconds()), 3, '0').slice(0, width)
opts.memoryLimit?.use(width - str.length) opts.memoryLimit?.use(width - str.length)
return padEnd(str, width, '0') return padEnd(str, width, '0')
}, },