dayjs: DayJS parses wrong year value for the date "0001-01-01"

Describe the bug When trying to parse the dates “0000-01-01” and “0001-01-01” DayJS returns the years 1900 and 1901 respectively:

const dayjs = require('dayjs')
console.log(dayjs("0001-01-01", "YYYY-MM-DD"))

Output:

d {
  '$L': 'en',
  '$d': 1901-01-01T03:06:28.000Z,
  '$x': {},
  '$y': 1901,
  '$M': 0,
  '$D': 1,
  '$W': 2,
  '$H': 0,
  '$m': 0,
  '$s': 0,
  '$ms': 0
}

Expected behavior The expected behavior is that the returned object has the correct year. Setting the year manually we can see the correct behavior working:

const dayjs = require('dayjs')
console.log(dayjs("2020-01-01", "YYYY-MM-DD").year(1))

Output:

d {
  '$L': 'en',
  '$d': 0001-01-01T03:06:28.000Z,
  '$x': {},
  '$y': 1,
  '$M': 0,
  '$D': 1,
  '$W': 1,
  '$H': 0,
  '$m': 0,
  '$s': 0,
  '$ms': 0
}

Information

  • Day.js Version v1.9.6
  • OS: Windows
  • Browser: N/A (Node.js v12.18.3)
  • Time zone: GMT-03:00

About this issue

  • Original URL
  • State: open
  • Created 4 years ago
  • Reactions: 5
  • Comments: 18 (5 by maintainers)

Most upvoted comments

This might be useful

Date - Two digit years map to 1900 – 1999

let date = new Date(98, 1)  // Sun Feb 01 1998 00:00:00 GMT+0000 (GMT)

// Deprecated method; 98 maps to 1998 here as well
date.setYear(98)            // Sun Feb 01 1998 00:00:00 GMT+0000 (GMT)

date.setFullYear(98)        // Sat Feb 01 0098 00:00:00 GMT+0000 (BST)

@iamkun yo, just created a PR to fix this issue in which I refactored a bit the parseDate method using the method setFullYear inspired by @naulacambra

all tests has passed, could you plz review this PR? we really need this fix for our project, thx in advance.

Just had the same issue, it’s related to https://github.com/iamkun/dayjs/pull/548.

I actually got a use case for this 😀 . I’m using a native date input and I’m parsing the user input as a Date, for form validation (checking if the date is after year X). When the user starts typing the year, like “01-10-2***”, the input value is “0002-01-01”. Which dayjs parses to the year 1901. For now I have to manually account for this and monkey-patch it.

Do you thing fixing this could cause issues ? Could someone rely on this behavior ?

So, we just can’t use this with a regular date input without writing a custom guard?

const date = countLeadingZeroes(dateString.split("-")[2] ?? "0000")) === 0 ? dayjs(dateString) : null

Seems pretty annoying considering the whole point of a date lib is to prevent having to parse and manipulate dates manually. Even more so when this is a problem for anyone who parses a date input’s value.

I have the same issue, this lib seems to use the following syntax new Date(1, 0, 0) instead of new Date('0001-01-01') which lead to have 1901 instead of 0001. It’s annoying when we try to convert a date which the user is currently typing.

I noticed a related bug that breaks the round-tripping scenario with input: format('YYYY') doesn’t include 4 digits for dates < 1000 as suggested by the documentation. For example 01/01/0001 is formatted as 1-01-01

I came here for exactly the same reason as @clementoriol . As you type in a standard <input type="date">, you’ll get through intermediate dates such as 0002-01-01 then 0020-01-01 etc. Because those dates don’t round-trip with Dayjs, it breaks my date input component.