Moment.js sets dates to 1 day behind
Asked Answered
D

3

15

I am using 2.22.1 to format dates.

When i put in a date that comes from a date selector, moment will put the date back one day. For example, when I try to format a date in the following way:

Example 1:

const day = new Date(value).getDate();
const month = new Date(value).getMonth();
const fullYear = new Date(value).getFullYear();
console.log('day', day); // 7
console.log('month', month); // 5
console.log('fullYear', fullYear); //2018

Formatting function:

moment.utc(new Date(month + ' ' + day + ' ' + fullYear), 'MM-DD-YYYY').format('DD-MM-YY')

Output: 06-05-18

Expected: 07-05-18

Example 2:

Input: Thu May 31 2018 00:00:00 GMT+0100 (GMT Summer Time)

Formatting function:

moment.utc(new Date(value)).format('DD-MM-YY')

Output: 30-05-18 Expected: 31-05-18

Divers answered 22/5, 2018 at 18:5 Comment(0)
G
33

moment.utc will convert the input to universal time.
You are running new Date(...) with an input that's based on GMT +1.

If you think about this, it makes total sense.
Your output is 30-05-18, because it's 11 PM / 23:00 o'clock on the previous day.

This (how ever) would in fact work:

moment('05-06-2018', 'MM-DD-YYYY').format('DD-MM-YY')
// alternatively (and preferrably) this:
moment.utc('05-06-2018', 'MM-DD-YYYY').format('DD-MM-YY')

and output: "06-05-18"

Because the non utc version does not take a time input in this example.

One of the reasons moment.js exists, is to get rid of Date in your code all together.
(Keep in mind tho, that Date has drastically improved now. DateTimeFormat is a game changer)
Please just read the momentjs documentation on how to properly use moment.

edit: If you want to process 400000 dates with this, I'd advise using RegExp, .split, .exec, .slice or Date instead.
(I can relate since I wrote a client sided Log parser with javascript generators and Service Workers for a statistical anti-cheat analysis)
I truly recommend playing around with such things to raise your knowledge.

Girosol answered 22/5, 2018 at 18:37 Comment(0)
E
7

I just ran into this issue and a quick fix I found for the time being processed in "Zulu time" (due to the Z at the end of the string) is to add .LocaleString() after the date variable.

I find that for data consistency, it's easier to store data in UTC time and then convert it to the locale string when displaying the data to the user.

For example, I'm using:

moment.utc(dateVariable.toLocaleString()).format("MM/DD/YYYY")
Ellora answered 17/3, 2021 at 15:10 Comment(0)
O
0

I had a similar problem while I was formatting a date inputed freely by a user. I wanted a final output in an ISO format, like this '2012-07-22T00:00:00z'

// for input: 22 Jul 2012
moment('22 Jul 2012').toISOString();
// '2012-07-21T18:30:00.000Z'

// If you do like given below, keepOffset: true.  
moment('22 Jul 2012').toISOString(true)
// '2012-07-22T00:00:00.000+05:30'

This helped me to solve problem of having a day prior set, just that I needed to Split out the string and append a z in the end as my backend needed that format. Either way, moment would just call native implementation of Date object. I am using moment 2.30.1

Anyone looking for ISO dates, hope this helps.

Orthodox answered 7/8 at 13:27 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.