Time validation with momentjs - javascript

I'm trying to do time calculation based on user input. Before firing the calculation, I'm using momentjs to validate that the user time input. It seems to be acting strangely. For example, here is undefined input in browser console:
>moment(undefined).isValid()
>true
How do I use momentjs to validate user input?
Edit:
It seems that in strict mode you can validate everything else but dates with timezone abbreviations (EEST):
Tue May 05 2015 12:00:00 GMT+0300 (EEST)
The z parameter used for abbreviation is deprecated due to browser incompatibility: https://github.com/moment/moment/issues/162

If you restrict the pattern of the input date - you must use something like this:
checksDate = moment(date, ['DD-MMMM-YYYY', 'DD.MM.YYYY', 'MM/DD/YYYY', 'YYYY-MM-DD'], true);
Where this array:
['DD-MMMM-YYYY', 'DD.MM.YYYY', 'MM/DD/YYYY', 'YYYY-MM-DD']
is yours patterns.
The Third parameter in my moment statement define that moment.js must use strict mode. That means you can't use "." instead "-" in ISO format: "1990-09-01", for example.
In Docs you can see this phrase:
Moment's parser is very forgiving, and this can lead to undesired
behavior. As of version 2.3.0, you may specify a boolean for the last
argument to make Moment use strict parsing. Strict parsing requires
that the format and input match exactly.
In browser's console:
moment(undefined).isValid()
true
moment(undefined, [], true).isValid()
false
But its strong recommended to use pattern as i used in my example above.
Because without it moment.js can do mistake for this dates:
"01.11.2000" and "11.01.2000" - it can be similar dates, then you use arbitrary user input.
read more:
moment.js Docs about validation
I hope, it's clear.

Related

trying to format date variable with moment and pass it to datetimepicker which results indeprecation warning

I am trying to format date variable and pass it to eonasdan datetimepicker for angular but no matter what I try to do I get
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.
Arguments:
below are my tryouts:
date from ajax - Wed, 05 Jul 2017 00:00:00 GMT
/*example1*/
angular.forEach(tickets, function(value, key){
$scope.startDate = new Date(value.start_date);
$scope.endDate = new Date(value.end_date);
});
/*example2*/
angular.forEach(tickets, function(value, key){
$scope.startDate = moment(startDate, "YYYY-MM-DD");
$scope.endDate = moment(value.end_date, "YYYY-MM-DD");
});
here are datetimepicker options
$scope.calendarWidgetOptions = {
format: 'YYYY-MM-DD',
minDate: moment().startOf('d')
};
I tried other stuff but can not make it work, and get rid of deprecation warning hence date is now visible in some browsers/timezones.
The implied question is 'Why am I getting this deprecation warning', and the answer is because you're making use of the moment function in a way that's deprecated and no longer officially supported.
From the link you provided:
"...moment construction using a non-iso string is deprecated. What this means is you can safely do..."
> moment("2014-04-25T01:32:21.196Z"); // iso string, utc timezone
> moment("2014-04-25T01:32:21.196+0600"); // iso string with timezone
> moment("2014 04 25", "YYYY MM DD"); // string with format
You're calling moment like this:
moment(value.end_date, "YYYY-MM-DD");
Which doesn't conform exactly to one of the strict signatures listed above, and so will be handled by the fuzzy handler that tries to resolve whatever value is passed in and return something usable, which is the functionality that's been deprecated.
You may be able to resolve this simply by matching the formatter exactly:
moment(value.end_date, "YYYY MM DD");
However you're also passing a Date object into moment, when it looks like it's expecting a String, so what you most likely want is to convert the Date to a string and then pass that and the correct formatter to moment.
moment(value.end_date.toISOString(), "YYYY MM DD");
or
moment(value.end_date.toISOString());
This will effectively submit something like this:
moment("2017-07-05T17:22:49.396Z", "YYYY MM DD");
or
moment("2017-07-05T17:22:49.396Z");
And this does match the expected signature and shouldn't throw the warning.

Deprecation warning: moment construction falls back to js Date (in html or ts) [duplicate]

I am using the following code to convert a server-side date-time to local time using moment.js.
moment(moment('Wed, 23 Apr 2014 09:54:51 +0000').format('lll')).fromNow()
But I am getting:
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.
It seems I cannot get rid of it! How can I fix it?
To get rid of the warning, you need to either:
Pass in an ISO formatted version of your date string:
moment('2014-04-23T09:54:51');
Pass in the string you have now, but tell Moment what format the string is in:
moment('Wed, 23 Apr 2014 09:54:51 +0000', 'ddd, DD MMM YYYY HH:mm:ss ZZ');
Convert your string to a JavaScript Date object and then pass that into Moment:
moment(new Date('Wed, 23 Apr 2014 09:54:51 +0000'));
The last option is a built-in fallback that Moment supports for now, with the deprecated console warning. They say they won't support this fallback in future releases. They explain that using new Date('my date') is too unpredictable.
As an alternative, you can suppress showing the deprecation warning by setting moment.suppressDeprecationWarnings = true;
The date construction in moment internally uses the new Date() in the javascript. The new Date() construction recognizes the date string in either RFC2822 or ISO formats in all browsers. When constructing a moment object with date not in these formats, the deprecation warning is thrown.
Though the deprecation warnings are thrown, for some formats, the moment object will be successfully constructed in Chrome, but not in Firefox or Safari. Due to this, processing the date in Chrome may give results as expected(not all the time) and throws Invalid Date in others.
Consider, 02.02.2018,
Chrome - moment("02.02.2018")._d -> Fri Feb 02 2018 00:00:00 GMT+0530 (India Standard Time)
Firefox - moment("02.02.2018")._d -> Invalid Date
Safari - moment("02.02.2018")._d -> Invalid Date
So the moment.js is used at your own risk in case the recommended/standard formats are not used.
To suppress the deprecation warnings,
As suggested by #Joe Wilson in previous answer, give the date format on moment construction.
Example : moment("02.05.2018", "DD.MM.YYYY").format("DD MM YYYY");
Give the date in ISO or RFC2822 format.
Example : moment("2018-02-01T18:30:00.000Z") - ISO Format
moment("Thu, 01 Feb 2018 18:30:00 GMT") - RFC2822 Format - Format in Github
As suggested by #niutech in previous answer, set
moment.suppressDeprecationWarnings = true;
I suggest to overwrite the input fallback in moment.
moment.createFromInputFallback=function (config){
config._d = new Date(config._i);
}
As (3) will suppress all the warnings, (4) will suppress only the date construction fallback. Using (4), you will get Invalid Date as the internal new Date() is used and other deprecations can be seen in console, so moment can be upgraded or the deprecated methods can be replaced in the application.
If your date is passed to you from an API as string(like my issue), you can use a filter to convert the string to a date for moment. This will take care of the moment construction warning.
$scope.apiDate = 10/29/2017 18:28:03";
angular.module('myApp').filter('stringToDate', function() {
return function(value) {
return Date.parse(value);
};
});
Add it to the view:
{{apiDate | stringToDate | amDateFormat:'ddd, MMM DD'}}
In my case I was trying to generate a date time to include in my form data. But the format of the string I had access to looked like "10-Sep-2020 10:10" so when trying to use moment like
myDate = '10-Sep-2020 10:10';
moment(myDate).format('YYYY-MM-DD HH:mm:ss');
I got the deprecation warning. There is no problem using a string to create the date but you just have to let moment know what it is you are passing in. As in explicitly state the format it is about to receive, for example
moment(myDate, 'DD-MMM-YYYY HH:mm').format('YYYY-MM-DD HH:mm:ss');
result: 2020-09-10 10:10:00
That's it, the warning goes away, moment is happy and you have a date time format ready for persistence.
As indicated in the above answers. Providing the date format should work.
Why would I be getting the deprecation message with the following line of code. I thought the String + format was suppose to remedy the issue. moment.tz('2015:08:20 14:33:20', 'YYYY:MM:DD HH:mm:ss', 'America/New_York'). Also, please not I do not have control over the date format being provide. I know I can convert it myself to 'YYYY-MM-DDTHH:mm:ss' then moment does not show the deprecation message. However, according to the documentation, the line of code should work. Here is the deprecation message I am seeing.
"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."
Moment’s usage is so widespread that it’s impossible to deprecate the current version over time. Check out this post on alternative options Migrating away from moment.js

Moment.js compare two date thrown a warning

I have created a simple app, which need a date comparison. I used Moment.js, and I have tried on answer on this question:
Compare two dates in JS
Moment js date time comparison
How to compare only date in moment.js
But all of them not working for me.
and now I use this code:
if(moment('09/12/2016').isAfter('09/11/2016')){
console.log("True")
} else {
console.log("False")
}
But in the console it's thrown a warning:
Deprecation warning: moment construction falls back to js Date. This
is discouraged and will be removed in upcoming major release. Please
refer to http://momentjs.com/guides/#/warnings/js-date/ for more info.
Everybody please help me. here's my fiddle https://jsfiddle.net/gq6ykw8L/
Your date string is ambiguous between DD/MM/YYYY and MM/DD/YYYY. If you refer to the link given in the warning (http://momentjs.com/guides/#/warnings/js-date/), it says:
This deprecation warning is thrown when no known format is found for a
date passed into the string constructor. To work around this issue,
specify a format for the string being passed to moment().
You need to use moment(String, Format) to specify the format of your date string.
moment('09/12/2016', 'DD/MM/YYYY');
moment('09/12/2016', 'MM/DD/YYYY');

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"

Moment.js : Format date according browser lang

I use this code to display a date in French format :
var dateToDisplay = moment(myDateInMS, "x").format("DD/MM/YYYY - hh:mm:ss"); // Output : "20/03/2016 - 12:35:32"
I would like to improve this display to have a better display according the browser language. How can i do that using moment ?
I do not recommend setting the locale depending on the browser language as it's not a clear signal of the actual locale of the user. E.g. a user may use an English operating system even though s/he's a French speaker.
That being said. Reading the language from the browser and setting Moment.js to the corresponding locale can be done this way:
var localeData = moment.localeData();
switch (navigator.language || navigator.userLanguage) {
case 'fr':
localeData = moment.localeData('fr');
break;
}
localeData.longDateFormat('LL'); // the example 'LL' will output date in "D MMMM YYYY format"
Notice that this is setting the locale of the entire Moment.js instance (which is probably what you want to do). Also notice that as of Moment.js 2.8.0, changing the global locale doesn't affect existing instances.
Also see
Changing locale globally
Long Date Format
Moment will actually search for substrings of the locale pulled from the browser in an attempt to pick the correct locale. Thus, there is no need to preparse or create a case statement.
As an example, moment has es as a locale, but not es-mx. If the browser is set to es-mx the locale function looks for es-mx and when it doesn't find it, falls back to es. Thus:
moment.locale('es-mx');
"es"
Meaning that for your purposes you can just do:
moment.locale(navigator.userLanguage || navigator.language);
Then when formatting your dates, use one of the locale specific formats to make them appropriate for the user:
moment().format('LL')
"1 de abril de 2016"
moment().format('L')
"01/04/2016"
For all of the localized formats and what they should produce, see the localized format section of the format documentation: http://momentjs.com/docs/#/displaying/format/

Categories