Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

dayjs.utc('....') parases milliseconds incorrectly #2459

Open
CramericaIndustries opened this issue Sep 23, 2023 · 9 comments
Open

dayjs.utc('....') parases milliseconds incorrectly #2459

CramericaIndustries opened this issue Sep 23, 2023 · 9 comments

Comments

@CramericaIndustries
Copy link

Describe the bug
When parsing a timestamp using utc() the Milliseconds part is interpreted incorrectly.
The timestamp is from a postgresql database. pgsql datatype is "timestamp without time zone".

let d = dayjs.utc("2022-10-01T11:34:02.02");
d.format("SSS"); // output is "002", correct would be "020"
d.toISOString(); // output is "2022-10-01T11:34:02.002Z"

d = dayjs.utc("2022-10-01T11:34:02.2");
d.format("SSS"); // output is "002", correct would be "200"
d.toISOString(); // output is "2022-10-01T11:34:02.002Z"

d = dayjs.utc("2022-10-01T11:34:02.020");
d.format("SSS"); // output is "020" (this is correct)
d.toISOString(); // output is "2022-10-01T11:34:02.020Z" (correct)

// If you append a "Z" to the timestamp millis are parsed correctly.
d = dayjs.utc("2022-10-01T11:34:02.02Z");
d.format("SSS"); // output is "020" (this is correct)
d.toISOString(); // output is "2022-10-01T11:34:02.020Z" (correct)

Expected behavior
".02" miliseconds should be interpreted as "20" milliseconds and not as "2"
".2" miliseconds should be interpreted as "200" milliseconds and not as "2"

Information

  • Day.js Version: tested on the day.js website in dev tools
  • OS: windows 10
  • Browser Firefox 117.0.1
  • Time zone: GMT+2
@mriedem
Copy link

mriedem commented Oct 11, 2023

I just figured out a bug we have today due to the same thing. I couldn't figure out why values coming out of our app code, using dayjs, weren't correct but the timestamps in the postgresql 12 database were.

It's easy to recreate with the latest version of dayjs:

osboxes@osboxes:~/ibmq/multi-channel-scheduler$ npm list dayjs
[email protected] /home/osboxes/ibmq/multi-channel-scheduler
└── [email protected]

osboxes@osboxes:~/ibmq/multi-channel-scheduler$ node
Welcome to Node.js v18.17.1.
Type ".help" for more information.
> const dayjs = require('dayjs').extend(require('dayjs/plugin/utc'))
undefined
> str = '2023-10-11 22:02:56.82'
'2023-10-11 22:02:56.82'
> dayjs.utc(str).toISOString()
'2023-10-11T22:02:56.082Z'
>

Comparing to moment 2.29.4:

> str = '2023-10-11 22:02:56.82'
'2023-10-11 22:02:56.82'
> moment.utc(str).toISOString()
'2023-10-11T22:02:56.820Z'

@mriedem
Copy link

mriedem commented Oct 11, 2023

@CramericaIndustries have you figured out a workaround?

@mriedem
Copy link

mriedem commented Oct 11, 2023

@CramericaIndustries have you figured out a workaround?

This seems to work:

> dayjs.utc(Date.parse('2023-10-11 22:02:56.82')).toISOString()
'2023-10-12T02:02:56.820Z'

As opposed to:

> dayjs.utc('2023-10-11 22:02:56.82').toISOString()
'2023-10-11T22:02:56.082Z'

@mriedem
Copy link

mriedem commented Oct 11, 2023

This seems to work:

> dayjs.utc(Date.parse('2023-10-11 22:02:56.82')).toISOString()
'2023-10-12T02:02:56.820Z'

Nevermind that, I lose the UTC...

@mriedem
Copy link

mriedem commented Oct 11, 2023

Here is my "it's late in the day" workaround - don't use dayjs:

  // workaround https://github.com/iamkun/dayjs/issues/2459 by using Date
  if (!str.endsWith('Z')) str += 'Z'
  return new Date(str).toISOString()

@CramericaIndustries
Copy link
Author

CramericaIndustries commented Oct 12, 2023

@CramericaIndustries have you figured out a workaround?
Yes, pretty similar to yours. I'm also appending the 'Z' when there are only one or two decimal digits.


if(typeof(value) === "string" && value.match(/\.\d{1,2}$/gi)) {
   value += "Z";
}
result = DayJS.utc(value);

@prgp
Copy link

prgp commented Nov 8, 2024

This is pretty embarrassing - the default Date is better than dayjs at parsing dates ...

More so since this bug still hasn't been fixed over a year later.

@stoyan-karev
Copy link

The same issue seems to occur when parsing a date with dayjs() even without the utc plugin.

new Date('2024-01-01T08:00:00.06').getMilliseconds(); // output is 60 ( correct )
dayjs('2024-01-01T10:00:00.06').millisecond(); // output is 6, should be 60

@stoyan-karev
Copy link

stoyan-karev commented Dec 10, 2024

This issue seems to be related - #2769
It has an open PR
#2771

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

No branches or pull requests

4 participants