Reputation: 3953
Why does moment.js UTC always show the wrong date. For example from chrome's developer console:
moment(('07-18-2013')).utc().format("YYYY-MM-DD").toString()
// or
moment.utc(new Date('07-18-2013')).format("YYYY-MM-DD").toString()
Both of them will return "2013-07-17" why is it returning 17th instead of 18th, that was passed in.
But if I use momentjs without the utc:
moment(new Date('07-18-2013')).format("YYYY-MM-DD").toString()
I get back "2013-07-18" which is what I also expect when using moment.js UTC.
Does this mean we cannot get the correct date when using moment.js UTC?
Upvotes: 129
Views: 296209
Reputation: 1
none of the above worked for me❌. I tried converting the date using moment()utc, use parseZone, but none of them worked.
✅Converting the date to ISO string using javascript's toISOString() did though ✅
// input date is "2023-09-28T00:00:00-05:00"
// timezone is chicago time GMT-5:00
const date_str = new Date(this.date);
const isoDate = date_str.toISOString();
// isoDate Result "2023-09-28T05:00:00.000Z"
// Before i used the isoString method, moment() would
// would always get the previous date
const startTime = moment(isoDate)
.set('hour', parseInt(momentConfigStartTimeOfDay.hour))
.set('minute', parseInt(momentConfigStartTimeOfDay.minute))
.format();
const endTime = moment(isoDate)
.set('hour', parseInt(momentConfigEndTimeOfDay.hour))
.set('minute', parseInt(momentConfigEndTimeOfDay.minute))
.format();
Upvotes: 0
Reputation: 31
use this :
return moment.utc(new Date(oData.CreatedAtUtc), 'MM/DD/YYYY h:mm A').local().format("YYYY-MM-DD HH:mm") + ' (' + timezoneAbbr + ')';
Upvotes: 2
Reputation: 16488
By default, MomentJS parses in local time. If only a date string (with no time) is provided, the time defaults to midnight.
In your code, you create a local date and then convert it to the UTC timezone (in fact, it makes the moment instance switch to UTC mode), so when it is formatted, it is shifted (depending on your local time) forward or backwards.
If the local timezone is UTC+N (N being a positive number), and you parse a date-only string, you will get the previous date.
Here are some examples to illustrate it (my local time offset is UTC+3 during DST):
>>> moment('07-18-2013', 'MM-DD-YYYY').utc().format("YYYY-MM-DD HH:mm")
"2013-07-17 21:00"
>>> moment('07-18-2013 12:00', 'MM-DD-YYYY HH:mm').utc().format("YYYY-MM-DD HH:mm")
"2013-07-18 09:00"
>>> Date()
"Thu Jul 25 2013 14:28:45 GMT+0300 (Jerusalem Daylight Time)"
If you want the date-time string interpreted as UTC, you should be explicit about it:
>>> moment(new Date('07-18-2013 UTC')).utc().format("YYYY-MM-DD HH:mm")
"2013-07-18 00:00"
or, as Matt Johnson mentions in his answer, you can (and probably should) parse it as a UTC date in the first place using moment.utc()
and include the format string as a second argument to prevent ambiguity.
>>> moment.utc('07-18-2013', 'MM-DD-YYYY').format("YYYY-MM-DD HH:mm")
"2013-07-18 00:00"
To go the other way around and convert a UTC date to a local date, you can use the local()
method, as follows:
>>> moment.utc('07-18-2013', 'MM-DD-YYYY').local().format("YYYY-MM-DD HH:mm")
"2013-07-18 03:00"
Upvotes: 211
Reputation: 241920
Both Date
and moment
will parse the input string in the local time zone of the browser by default. However Date
is sometimes inconsistent with this regard. If the string is specifically YYYY-MM-DD
, using hyphens, or if it is YYYY-MM-DD HH:mm:ss
, it will interpret it as local time. Unlike Date
, moment
will always be consistent about how it parses.
The correct way to parse an input moment as UTC in the format you provided would be like this:
moment.utc('07-18-2013', 'MM-DD-YYYY')
Refer to this documentation.
If you want to then format it differently for output, you would do this:
moment.utc('07-18-2013', 'MM-DD-YYYY').format('YYYY-MM-DD')
You do not need to call toString
explicitly.
Note that it is very important to provide the input format. Without it, a date like 01-04-2013
might get processed as either Jan 4th or Apr 1st, depending on the culture settings of the browser.
Upvotes: 41