NibblyPig
NibblyPig

Reputation: 52942

moment.js will not parse UK format date even when setting the locale

Quite simply, this is my code:

http://jsfiddle.net/NibblyPig/k9zb4ysp/

moment.locale('en-GB');

var d = moment('22/12/2019');

alert(d);

I would expect this to parse, however it says invalid date.

I have referenced moment.js and the locale/en-gb.js

I'm writing a global control so the date may come in in a variety of formats.

If I put in a variety of American dates they all work, for example 12/12/2019, 12/12/2019 23:04 etc.

However the locale command does not appear to do anything and I cannot get a single date to parse. What am I doing wrong?

Upvotes: 5

Views: 3466

Answers (5)

Luke Sims
Luke Sims

Reputation: 1

You can return a date using moment.js in a desired format -

return moment(aDateVar).format('DD/MM/YYYY');

Upvotes: 0

davnicwil
davnicwil

Reputation: 30957

This won't solve every usecase, but in your specific example if you want just a simple date (with no time component) auto-parsed in UK format you can just use the 'L' format string having set the locale to 'en-GB'

Your example with this change (your jsfiddle also)

moment.locale('en-GB');

// just pass 'L' i.e. local date format as a parsing format here
var d = moment('22/12/2019', 'L'); 

alert(d);

It's quite nice because you get the auto parsing of various formats you wanted for free. For instance this works just the same:

var d = moment('22-12-2019', 'L'); 

Upvotes: 1

VincenzoC
VincenzoC

Reputation: 31482

I think that there is no need to write your own complex logic to parse your input, you can use moment(String, String) (or moment(String, String[], String, Boolean)), as suggested by Thales Minussi's answer.

moment(String) is the good choice only if your input is in ISO 8601 or RFC 2822 compliant form.

In your case, you can probably use Localized formats listed in the format section of the docs. If you have a list of possible formats, I think that the best choice is tho use moment(String, String[]).

Please note that, by default: Moment's parser is very forgiving, so using default Forgiving Mode will handle "any" character as separator.

Here a live sample:

moment.locale('en-GB');

['22/12/2019', '22/12/2019 15:00',
 '22-12-2019', '22-12-2019 15:00',
 '1-3-2019', '1-12-2019', '22-1-2019'
].forEach((elem) => {
  var d = moment(elem, 'L LT');
  console.log(d.format());
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.24.0/moment.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.24.0/locale/en-gb.js"></script>

Upvotes: 2

NibblyPig
NibblyPig

Reputation: 52942

Still hoping there's a nice moment js way to do this but in the meantime I just bashed this together. Pretty nasty and it will probably go wrong in 80 years or so.

http://jsfiddle.net/NibblyPig/k9zb4ysp/22/

var a = "23/03/19 12:42:21.123";

var datePart = a.substring(0, a.indexOf(" "));
var timePart = a.substring(a.indexOf(" ") + 1);

var dateParts = datePart.split("/");

if (dateParts[0].length == 1) dateParts[0] = "0" + dateParts[0];
if (dateParts[1].length == 1) dateParts[1] = "0" + dateParts[1];
if (dateParts[2].length == 2) {

    var threshold = parseInt(new Date().getFullYear().toString().substring(2)) +  10;

if (parseFloat(dateParts[2]) > threshold ) {
    dateParts[2] = "19" + dateParts[2];
  }
  else
  {
        dateParts[2] = "20" + dateParts[2];
  }
}

alert (parseFloat(dateParts[2] + dateParts[1] + dateParts[0] + timePart.replace(/:/g, "").replace(/\./g, "")));

Upvotes: 1

Thales Minussi
Thales Minussi

Reputation: 7215

You need to pass the format as the second argument for moment(), as discussed here:

moment.locale('en-GB');

var d = moment('22/12/2019', 'DD/MM/YYYY');

alert(d);

https://jsfiddle.net/a4gu6kfz/

From the docs:

If you know the format of an input string, you can use that to parse a moment.

moment("12-25-1995", "MM-DD-YYYY");

Upvotes: 4

Related Questions