dayjs
dayjs copied to clipboard
customParseFormat strict mode bug
Describe the bug Using the format string "YYYY-MM-DD HH:mm:ss ZZ", parsing certain strings returns Invalid Date when it should return a date:
var format = "YYYY-MM-DD HH:mm:ss ZZ";
var ok = dayjs("2018-03-01 00:01:00 +0000", format, true);
var bad = dayjs("2018-04-01 00:01:00 +0000", format, true);
where bad is:
{
"$D": 1
"$H": 1
"$L": "en"
"$M": 3
"$W": 0
"$d": Invalid Date
"$m": 1
"$ms": 0
"$s": 0
"$u": undefined
"$y": 2018
}
The parsing is successful if strict mode is not used. The problem seems to be in the customParseFormat.js line:
if (isStrict && date !== this.format(format)) {
where the date that the plugin has parsed is not matching the default output from dayjs.format(). In the above case:
"2018-04-01 00:01:00 +0000" !== "2018-04-01 01:01:00 +0100"
but the same bug will effect parsing any date where the timezone doesn't match whatever local timezone/dst dayjs uses. eg. "2018-03-01 00:01:00 +0600", "2018-04-01 00:01:00 -0200", etc.
Expected behavior
bad should be a valid date object.
Information
- Day.js Version: v1.8.28
- OS: Windows 7
- Browser: Firefox 77, Chrome 83
- Time zone: UTC+00:00 DST (British Summer Time)
We have the same problem. I created this codesandbox example to reproduce the issue
R.I.P 👌
I've looked into the code and so far I see only two options for how this bug could be fixed:
- The timezone information that is extracted by makeParser() could be passed back to the main method in addition to the parsed Date object. It can then be used to format the final result with a custom timezone before the string comparison is made. This however would mean to either require the timezone plugin for the customParseFormat plugin to work or to recreate this functionality in customParseFormat, which might be overkill
- Rework how strict parsing in customParseFormat works by giving each segment expression information on how to enforce a strict format
Bug confirmed. Strict mode does not work good with parsing timezone (ZZ)
I'm looking for a way to solve it.
I am trying to migrate some code from moment to dayjs, and this strict check is a big problem for me :(, any idea how to solve it?
@iamkun is there any known workaround available right now? Or do you eventually have an estimated time until when this can be looked into? Thanks in advance
@iamkun I've created a pull request which tries to fix this issue (https://github.com/iamkun/dayjs/pull/1467). The following has been done to fix it: The parseFormattedInput function returns a UTC object for dates with timezones. When using dayjs().format() it usually formats the date with the current timezone. This fix manually removes the current timezone's offset and manually adds the originally parsed offset. Then the timezone part (+/-xx:xx or +-xxxx) will be removed from both strings and the timestamp without the timezone can be compared correctly.
Any updates on this? Looks like the PR #1467 has conflicts which need to be resolved.
Kinda strange that dayjs can't handle YYYY-MM-DDTHH:mm:ss.SSSZ as format in strict mode, which is the default format from what I read in the docs.
@BreakBB thank you for the hint. I've merged it now with dev, updated the code and the tests are passing. Now waiting for further feedback from @iamkun :+1:
@iamkun is there anything else we can do to help get this pull request merged?
@iamkun Just a friendly reminder :)
any news about the problem?
Is there any progress for this?
any news about the timezone parsing issue? It will be great to use it properly as I'm migrating from luxon to dayjs
any news? 😅