Skip to content

fix(customParseFormat): preserve UTC mode when format is an array#3023

Open
Jadu07 wants to merge 2 commits intoiamkun:devfrom
Jadu07:fix/utc-custom-parse-format-array-format
Open

fix(customParseFormat): preserve UTC mode when format is an array#3023
Jadu07 wants to merge 2 commits intoiamkun:devfrom
Jadu07:fix/utc-custom-parse-format-array-format

Conversation

@Jadu07
Copy link
Copy Markdown

@Jadu07 Jadu07 commented Mar 15, 2026

What this PR does

Fixes #3013dayjs.utc() ignores UTC mode when the format argument is an array.


The bug

If you pass an array of formats to dayjs.utc() (via the customParseFormat plugin), the date gets parsed in local time instead of UTC. No error is thrown, which makes the bug really hard to spot — your tests might pass fine in TZ=UTC but silently break everywhere else.

dayjs.extend(utc)
dayjs.extend(customParseFormat)

// single format — works fine
dayjs.utc('1995-05-01', 'YYYY-MM-DD').toISOString()
// → '1995-05-01T00:00:00.000Z' ✓

// array format — parsed in local time before this fix
dayjs.utc('1995-05-01', ['YYYY-MM-DD', 'YYYY-M-D']).toISOString()
// → '1995-05-01T23:00:00.000Z' in UTC+1 ✗

Why it happened

In customParseFormat/index.js, the format instanceof Array branch loops through each format and tries it with d.apply(this, args). The problem is that d.apply just calls the regular dayjs() constructor, which has no idea about utc: true. So every format attempt ends up using local time.

Meanwhile, the single-format code path calls parseFormattedInput(date, format, utc, d), which correctly threads the utc flag through.


The fix

One line change — once we find a valid format, compute this.$d using parseFormattedInput with the utc flag instead of blindly copying result.$d:

  if (result.isValid()) {
-   this.$d = result.$d
+   this.$d = utc
+     ? parseFormattedInput(date, format[i - 1], utc, d)
+     : result.$d

Tests

Added two regression tests to test/plugin/utc.test.js:

  • first format in the array matches → result is UTC midnight ✓
  • second format in the array matches → result is UTC midnight ✓

Full suite: 774 tests, 93 suites — all passing. npm run lint is clean too.

When dayjs.utc(date, [...formats]) was called with an array of formats,
dates were silently parsed in local time instead of UTC. The array branch
was calling d.apply() (the default dayjs constructor) which has no
awareness of the utc:true flag.
Fix: after a valid format is found, recompute this.$d via
parseFormattedInput() with the utc flag — matching the behaviour of the
single-format code path.
Fixes: #<issue-number>
@Jadu07
Copy link
Copy Markdown
Author

Jadu07 commented Mar 15, 2026

@iamkun @pavan-sh pls review this pr.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Passing array value to format param to dayjs.utc() silently disables utc mode

1 participant