2

I bumped into a situation where I'm getting a string indicating only the month and year of a date, and I need to create a Date object out of it. If I pass just the string, e.g. "February 2020" into a Date constructor, I strangely get back the the day of the previous month, i.e. in this case 2020-31-01. Thus, I need to always add 1 day to get the proper month in the Date object.

Here is the code to replicate:

var date_str = "February 2020";
var dt = new Date(date_str)

console.log(dt)    // Returns : 2020-01-31T23:00:00.000Z (????)

dt.setDate(dt.getDate() + 1);

console.log(dt)   // Returns : 2020-02-01T23:00:00.000Z

Any idea what the logic is behind this rather strange behaviour, or do I miss something here?

Update

Have accepted the first answer as being relevant, thus the main question is solved. However, just to add to the confusion: the code snippet I included runs as described with node. Using EXACTLY the same logic in a Vue.js application return the correct Date. Very strange!

Peter K.
  • 517
  • 3
  • 19
  • 10
    Feb 1st 0:00 in your local time is Jan 31st 23:00 in UTC. – NineBerry Jan 27 '20 at 11:29
  • I would have used moment, if it is really understood, it deals with issues like this (https://momentjs.com/) – Iria Jan 27 '20 at 11:29
  • 3
    To give a meaningful answer on how to solve this, it is important to know what you want to do with this variable later on. – NineBerry Jan 27 '20 at 11:33
  • https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date/Date#Timestamp_string – Jonathan Jan 27 '20 at 11:37
  • Side note: While chrome seems to be able to handle the string "February 2020", Firefox, Edge and IE all cannot handle it correctly, – NineBerry Jan 27 '20 at 11:38
  • JavaScript counts months from 0 to 11. https://stackoverflow.com/questions/2552483/why-does-the-month-argument-range-from-0-to-11-in-javascripts-date-constructor – Jins Thomas Shaji Jan 27 '20 at 11:39
  • @NineBerry OPs format is not according to spec, therefor there is no guarantee that browser handle it correctly or at all. – Jonathan Jan 27 '20 at 11:39
  • Where are you even seeing this? I can't replicate the behaviour. Partly because `"February 2020"` is absolutely non-standard date string, so it's platform dependent. Firefox just considers it invalid, while Chrome seems to consider it 00:00 UTC in 1st of February, *not* the local, so you don't get a backwards shift. – VLAZ Jan 27 '20 at 11:39
  • @VLAZ Chrome on my system interprets it as the local time, but also outputs in local format when doing console.log(). You will see console.log producing the UTC format when executing the code on online JavaScript playgrounds. – NineBerry Jan 27 '20 at 11:41
  • @NineBerry there is no "correctly" here. A non-standard date string *cannot* be handled "correctly" - at best you can hope for it to not be considered invalid. Although IMO - I'd rather have it as invalid. Handling this (or not) is up to the environment, so by definition it's all various forms of damage control. – VLAZ Jan 27 '20 at 11:41

3 Answers3

2

"February 2020" is not a valid input according to the specification thus you should not rely on it to work.

You should convert your input to one that is according to spec and then decide whether you need local time or UTC.

Handling time(zones) is one of the hardest things in JavaScript and I strongly recommend that you do not try to reinvent the wheel here yourself as it is really easy to mess up. Libraries like momentjs can help you here.

Jonathan
  • 8,771
  • 4
  • 41
  • 78
  • "*Handling time(zones) is one of the hardest things in JavaScript*" I've yet to find a language that makes it easy or at least *normal*. Dates are always a pain no matter what code you're writing. – VLAZ Jan 27 '20 at 12:33
1

Actually you are passing February 2020 into the date Constructor , and its assumes the

date as 1 February 2020 thus it give the output as its UTC date which may be previous

day depending on your region

Sreeraj_ms
  • 541
  • 3
  • 13
1

Use moment.js library, it will give perfect.

moment("February 2020").format('L')
"02/01/2020"

enter image description here

Ankit Kumar Rajpoot
  • 5,188
  • 2
  • 38
  • 32