moment.js formatting date wrong - javascript

I'm trying to get upcoming date using moment.js. The date is obtained, but it's formatted wrongly. According to docs, format('l') formats the date in dd/mm/yyyy format and format('L') formats date in mm/dd/yyyy. but I'm getting the same output for both. Here is my code.
let next = moment().add(30, 'days').format('l'); // Output 10/16/2019
let next = moment().add(30, 'days').format('L'); // Output 10/16/2019
let next = moment().add(30, 'days').format('DD/MM/YYYY'); // Works fine
I tried i with moment.js v2.24.0 what's wrong in here? am I missing something or doing it wrong way?

According to docs, format('l') formats the date in dd/mm/yyyy format and format('L') formats date in mm/dd/yyyy.
No, that isn't what the documentation says:
Localized formats
Because preferred formatting differs based on locale, there are a few tokens that can be used to format a moment based on its locale.
There are upper and lower case variations on the same formats. The lowercase version is intended to be the shortened version of its uppercase counterpart.
Month numeral, day of month, year: L 09/04/1986
l 9/4/1986
There's nothing there saying L will use one field order and l another.
It's using your current Moment locale to format the date. See the i18n section for how to set locales, globally or per instance.

According to docs
moment().format('L'); // 09/16/2019
moment().format('l'); // 9/16/2019
https://momentjs.com/

Related

Weird ISO formatted Datestring to Javascript Date

I've got a Datestring like this one: 20171010T022902.000Z and I need to create Javascript Date from this string. new Date('20171010T022902.000Z') would return Invalid Date.
I saw that it's possible to use moment.js for this purpose but I am not sure how I would specify the according format for my given example. I found this example from another thread:
var momentDate = moment('1890-09-30T23:59:59+01:16:20', 'YYYY-MM-DDTHH:mm:ss+-HH:mm:ss');
var jsDate = momentDate.toDate();
Question:
How can I create a JavaScript date from a given Datestring in this format: 20171010T022902.000Z (using moment)?
Your input (20171010T022902.000Z) matches known ISO 8601 so you can simply use moment(String) parsing method. In the Supported ISO 8601 strings section of the docs you will find:
20130208T080910.123 # Short date and time up to ms
Then you can use toDate() method
To get a copy of the native Date object that Moment.js wraps
Your code could be like the following
var m = moment('20171010T022902.000Z');
console.log( m.format() );
console.log( m.toDate() );
<script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.18.1/moment.min.js"></script>
Note that this code does not shows Deprecation Warning (cited in Bergi's comment) because you input is in ISO 8601 known format. See this guide to know more about this warning.
Moreover "By default, moment parses and displays in local time" as stated here so format() will show the local value for your UTC input (20171010T022902.000Z ends with Z). See moment.utc(), utc() and Local vs UTC vs Offset guide to learn more about moment UTC mode.
I think you can do this without moment.js,.
Basically extract the parts you need using regex's capture groups, and then re-arrange into a correct format for new Date to work with.
var dtstr = '20171010T022902.000Z';
var dt = new Date(
dtstr.replace(/^(\d{4})(\d{2})(\d{2})T(\d{2})(\d{2})(\d{2})(\.\d{3}Z)$/,
"$1-$2-$3T$4:$5:$6$7"));
console.log(dt);
console.log(dt.toString());
If you are using moment.js anyway, this should work ->
var dt = moment("20171010T022902.000Z", "YYYYMMDDTHHmmss.SSSSZ");
console.log(dt.toString());
<script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.19.1/moment.min.js"></script>

Using _i with moment js is not working when using it in with if condition

I am using _i in momentjs with if condition but it is not giving expected output.
Here is my code:
var output = "07-14-2017";
var selectedDates = "06-15-2018";
if(moment(output)._i <= moment(selectedDates)._i)
{
console.log(output date is less than or equal selected date);
}
else
{
console.log(output date is greater than selected date);
}
Here my output date is of 2017 and selecteddates is of 2018, still it is giving me an output of 'output date is greater than selected date'. It should give me an output 'output date is less than or equal selected date'.
I have given all jQuery and momentjs files references properly.
There are 2 issue with your code:
You are trying to parse using moment(String) a string that is neither in RFC2822 or ISO 8601 recognized format, so your code gives Deprecation warning. You have to use moment(String, String) instead.
You are using _i that as Internal Properties guide states:
[...] the values of _d and any other properties prefixed with _ should not be used for any purpose.
To compare moment objects you can use isSameOrBefore, isAfter, isBefore and the others methods listed in the Query section of the docs.
Here a working sample:
var output = "07-14-2017";
var selectedDates = "06-15-2018";
if(moment(output, 'MM-DD-YYYY').isSameOrBefore(moment(selectedDates, 'MM-DD-YYYY')))
{
console.log("output date is less than or equal selected date");
}
else
{
console.log("output date is greater than selected date");
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.18.1/moment.min.js"></script>
_i returns string which is not correct and also you should not use it as per #Andreas comments.
You can use below code gives correct comparison.
moment(selectedDates).isAfter(output);
I just tested your code and it works in Chrome 59, however it threw the following warning:
Deprecation warning: value provided is not in a recognized RFC2822 or
ISO format. moment construction falls back to js Date(), which is not
reliable across all browsers and versions. Non RFC2822/ISO date
formats are discouraged and will be removed in an upcoming major
release. Please refer to
http://momentjs.com/guides/#/warnings/js-date/ for more info.
It's possible that your issues are with your browser's javascript engine's implementation of Date(), as hinted in the warning above.
I would recommend you reformat your dates to a more moment-friendly format and try again.

Get the given date format (the string specifying the format) in javascript or momentjs

Given a datestring, how can I get the format string describing that datestring?
Put another way, how can I get the format string that Date() or MomentJS (might be different for each, that's fine) would use to parse that datestring if one didn't pass an explicit format to use?
So given '2016-01-01' it should output something like 'YYYY-MM-DD', for example.
(I am aware this is a simple question and may have an answer somewhere, but it is difficult to word concisely, so I could only find questions and answers about how to parse datestrings or how to display dates. None about how to output the format itself.)
Consolidating information from Matt Johnson's answer, some comments, and my own contribution.
With Moment.js (version 2.10.7+), you can use the Creation Data API. Something like this in Node.js:
moment('2016-01-01 00:00:00').creationData().format
outputs
'YYYY-MM-DD HH:mm:ss'
Just as any date parsing is, there is ambiguity about the format of many datestrings due to things such as locale (the order of months and days are switched between the US and Europe, for example). But the above method is sufficient for me.
You can't, without having additional information, such as the locale. For example, 01/12/16 could be Jan 12, 2016, December 1, 2016, or December 16, 2001.
Even when you know the locale, there are several places in the real world where more than one date format is used, depending on context.
See https://en.wikipedia.org/wiki/Date_format_by_country
However, if you are just trying to determine which one of multiple known formats was used to parse the input string, moment has an API for that called Creation Data. For example:
var m = moment("2016/06/10", ["YYYY-MM-DD", "MM/DD/YYYY"], true);
var f = m.creationData().format; // "MM/DD/YYYY"

Show long date format without the year in momentjs

I am using this for date formatting at the moment:
var format = moment().localeData(locale).longDateFormat("L");
return moment(dateObj).format(format);
Where locale can be any market eg. en-US, fr-FR, en-GB etc...
However, the L date format has the MM/DD/YYYY (it changes per market, of course) and I just want MM/DD. I didn't find any format that provides this kind of string. Does anyone know how I can achieve the desired functionality?
It might be a bit more hacky than you're looking for, but....
var format = moment().localeData('en').longDateFormat("L");
moment().format(format).substr(0,moment().format(format).length-5);

Time Zone Offset Calculations

Let's suppose the server gives the date in this format:
var date = '2012-08-08T15:04:33+0200';
As you can see the previous date has a Timezone offset of two hours.
Let's suppose I need to display the same date in different places having different timezone.
What is the proper way to display the date in different clients having the different time zone using moment.js
I did try the following but I am not sure because I cannot test it.
moment(date, "YYYY-MM-DDTHH:mm:ss").fromNow();
According the documentation it should be enough just passing the following parameter ´Z´ or ZZ according your date format.
So in your case it should be:
var date = '2012-08-08T15:04:33+0200';
moment(date, "YYYY-MM-DDTHH:mm:ssZ").fromNow();

Categories