Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion src/constant.js
Original file line number Diff line number Diff line change
Expand Up @@ -27,4 +27,4 @@ export const INVALID_DATE_STRING = 'Invalid Date'

// regex
export const REGEX_PARSE = /^(\d{4})[-/]?(\d{1,2})?[-/]?(\d{0,2})[Tt\s]*(\d{1,2})?:?(\d{1,2})?:?(\d{1,2})?[.:]?(\d+)?$/
export const REGEX_FORMAT = /\[([^\]]+)]|YYYY|YY|M{1,4}|D{1,2}|d{1,4}|H{1,2}|h{1,2}|a|A|m{1,2}|s{1,2}|Z{1,2}|SSS/g
export const REGEX_FORMAT = /\[([^\]]+)]|YYYY|YY|M{1,4}|D{1,2}|d{1,4}|H{1,2}|h{1,2}|a|A|m{1,2}|s{1,2}|Z{1,2}|S{1,3}/g
4 changes: 4 additions & 0 deletions src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -328,6 +328,10 @@ class Dayjs {
return String(this.$s)
case 'ss':
return Utils.s(this.$s, 2, '0')
case 'S':
return String(Math.floor(this.$ms / 100))
case 'SS':
return Utils.s(Math.floor(this.$ms / 10), 2, '0')
case 'SSS':
return Utils.s(this.$ms, 3, '0')
case 'Z':
Expand Down
63 changes: 63 additions & 0 deletions test/plugin/customParseFormat_S_SS.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
import dayjs from '../../src'
import customParseFormat from '../../src/plugin/customParseFormat'

dayjs.extend(customParseFormat)

// Issue #1331: S and SS format tokens are not supported by the base format() function
// This means:
// 1. dayjs().format('S') returns literal 'S' instead of first digit of milliseconds
// 2. dayjs().format('SS') returns literal 'SS' instead of first two digits of milliseconds
// 3. customParseFormat strict mode fails with S/SS tokens

describe('S and SS format tokens', () => {
describe('base format() support', () => {
it('format S returns first digit of milliseconds (hundreds)', () => {
expect(dayjs('2021-01-01T00:00:00.500').format('S')).toBe('5')
expect(dayjs('2021-01-01T00:00:00.900').format('S')).toBe('9')
expect(dayjs('2021-01-01T00:00:00.000').format('S')).toBe('0')
})

it('format SS returns first two digits of milliseconds', () => {
expect(dayjs('2021-01-01T00:00:00.520').format('SS')).toBe('52')
expect(dayjs('2021-01-01T00:00:00.050').format('SS')).toBe('05')
expect(dayjs('2021-01-01T00:00:00.000').format('SS')).toBe('00')
})

it('format SSS still works (3 digits)', () => {
expect(dayjs('2021-01-01T00:00:00.520').format('SSS')).toBe('520')
expect(dayjs('2021-01-01T00:00:00.005').format('SSS')).toBe('005')
})
})

describe('customParseFormat strict mode with S/SS tokens', () => {
it('SS strict mode parses 2-digit fractional seconds correctly', () => {
const result = dayjs(
'2021-01-01T00:00:00.52',
'YYYY-MM-DDTHH:mm:ss.SS',
true
)
expect(result.isValid()).toBe(true)
expect(result.millisecond()).toBe(520)
})

it('S strict mode parses 1-digit fractional seconds correctly', () => {
const result = dayjs(
'2021-01-01T00:00:00.5',
'YYYY-MM-DDTHH:mm:ss.S',
true
)
expect(result.isValid()).toBe(true)
expect(result.millisecond()).toBe(500)
})

it('SSS strict mode still works', () => {
const result = dayjs(
'2021-01-01T00:00:00.520',
'YYYY-MM-DDTHH:mm:ss.SSS',
true
)
expect(result.isValid()).toBe(true)
expect(result.millisecond()).toBe(520)
})
})
})