0

I was working on a JavaScript application where I set the default "starting date" to 1700-01-01 if the user only selects an "ending date" and doesn't select a beginning date. I chose 1700-01-01 because that's the earliest date that can be stored in a Microsoft SQL Server (or at least the default value). I then store this value in local storage and parse it again later. So effectively I execute these three commands at some point:

testDate = new Date(1700, 0, 1, 0, 0, 0, 0)
testDateStr = testDate.toString()
testDateReparsed = new Date(testDateStr)
console.log(testDateReparsed );

However, testDateReparsed ends up being the date: Thu Dec 31 1699 23:59:24!

This same behavior doesn't happen with dates after 1700-01-01, and also happens with dates before 1700-01-01. So if I repeated the same code except the year was 2000 instead of 1700, testDateReparsed would be 2000-01-01 as expected. If the year was 1500 instead of 1700, testDateReparsed would be 1499-12-31 like with the year 1700.

What is the cause of this? Is this a know JavaScript bug or am I missing something?

HoldOffHunger
  • 18,769
  • 10
  • 104
  • 133
Cole Medin
  • 21
  • 1
  • 6
  • does storing the valueOf/getTime have the same issue? – dandavis Oct 13 '21 at 17:08
  • This could be solved calling `toJSON()` instead of `toString()`. I don't know yet why toString() causes this issue. – Lucas David Ferrero Oct 13 '21 at 17:20
  • @LucasDavidFerrero mostly because parsing dates from string is extremely error prone and never to be taken likely. Small exception for ISO 8601 formatted dates (which `toJSON()` produces) those can also surprise you occasionally - try `new Date("2021-07-01T00:00:00Z")` vs `new Date("2021-07-01T00:00:00")` or `new Date("2021-07-01")` for example - the first one is considered UTC, the last two are interpreted as local time. – VLAZ Oct 13 '21 at 17:27
  • What time zone are you working in? (that Date constructor respects local time, so I suppose you're either using UTC or some time zone which is very similar; the difference might matter.) – rici Oct 13 '21 at 17:31
  • The values passed to the constructor are treated as local. Offsets prior to about 1900 were typically local to cities and were based on local mean solar noon, hence offsets down to the second rather than current offsets that are 15 or 30 minute multiples. Log the *toString()* value for both dates and they're the same. See [*Browsers, time zones, Chrome 67 Error (historic timezone changes)*](https://stackoverflow.com/questions/50609860/browsers-time-zones-chrome-67-error-historic-timezone-changes). – RobG Oct 13 '21 at 20:43
  • @VLAZ—the format of *toString* has been standardised since ECMAScript 2018 (I think) and the built–in parser has been required to correctly parse it since about the same vintage, so that isn't the problem (though you are correct that using the built–in parser is fraught and not recommended). ;-) – RobG Oct 13 '21 at 21:07
  • Thanks for the responses, everyone! For reference I was working in central time (CDT). I appreciate what these responses have given me to think/what they've helped me understand. – Cole Medin Oct 13 '21 at 21:08

0 Answers0