Skintkingle
Skintkingle

Reputation: 1579

MomentJs output Date of toDate() is incorrect

I've started using momentJs in an Angular/Typescript project. (Included incase it's relevant in any way although I very much doubt it)

In the run method of my module I call

moment.locale(window.navigator.language);

which correctly sets the locale to en-GB in my instance. Further down the line I use moment to parse a GB time.

when doing the following:

var mom = moment("24/11/2015 00:00:00");

for example. This populates a new moment object using the defaults set on the moment global (If i understand how it should work correctly). moms date is set to 2016-12-11T00:00:00.000Z. This clearly means it's parsed the given string in en-US instead of en-GB which was set via Locale in a default setting prior to this call. Is there anything I've missed in configuration/setup of moment which would make this not work? I've also inspected the _locale property of my variable. mom._locale is set to en-gb and I can see the L,LL,LLL etc etc formats are all en-GB formatted values (as they should be).

running mom.toDate(); unsurprizingly returns the 2016 date stored internally by the moment object.

Some misc information I forgot to include:

I am using the latest release of momentjs from NuGet (Version 2.10.6 at time of writing) and I've included moment-with-locales.js in my HTML

Upvotes: 0

Views: 1711

Answers (3)

Skintkingle
Skintkingle

Reputation: 1579

So I got around this by fetching the locale data from moment and just passing it into the format parameter. Considering the example input of "24/11/2015 00:00:00" I would structure my format as below:

var format = moment.localeData().longDateFormat('L') + " " + moment.localeData().longDateFormat("LTS");

this generates the format mask of "DD/MM/YYYY HH:mm:ss".

You can mix and match whatever formats you want and this will be locale specific to whatever you set moment.locale("") to be (presuming you have the locale information setup in moment already)

This is a crazy workaround and I'm surprised that moment doesn't presume locale information as default when parsing. TJCrowder has raised an issue on Github with the moment guys which I suggest anyone who cares should comment on. https://github.com/moment/moment/issues/2770

Upvotes: 1

thelastshadow
thelastshadow

Reputation: 3654

You're probably better off passing the format to moment directly and validating the string before hand. This will ultimately reduce the amount of debugging you'll need to do and get you up and running straight away.

var mom = moment("24/11/2015 00:00:00", "DD/MM/YYYY HH:mm:ss");

You could try the new(ish) Intl API but browser support is limited (IE11+), so I would recommend having a user select the month in a dropdown or something to force them to input a certain way.

Upvotes: 0

T.J. Crowder
T.J. Crowder

Reputation: 1074809

Using any recent version of MomentJS, you should see why in the console:

Deprecation warning: moment construction falls back to js Date. This is discouraged and will be removed in upcoming major release. Please refer to https://github.com/moment/moment/issues/1407 for more info.

enter image description here

Unless you specify a format string, MomentJS relies on the Date object's parsing, and unfortunately, regardless of locale the Date object will, with a string using /, assume U.S. format. One of the many, many things that aren't quite right with Date.

You'll need to use a format string, or supply the string in the simplified ISO-8601 format used by Date. From Parse > String:

When creating a moment from a string, we first check if the string matches known ISO 8601 formats, then fall back to new Date(string) if a known format is not found.

var day = moment("1995-12-25");

Warning: Browser support for parsing strings is inconsistent. Because there is no specification on which formats should be supported, what works in some browsers will not work in other browsers.

For consistent results parsing anything other than ISO 8601 strings, you should use String + Format.

Upvotes: 2

Related Questions