dayjs() telling me invalid date for this date string - javascript

DayJs
Using it on the browser if that matters (firefox + Vue + typescript).
This is my date string
2021-02-05 12:00 AM
It fusses about the AM/PM in my code:
const dateObj: any = dayjs('2021-02-05 12:00 AM').format('YYYY-MM-DD hh:mm A');
The output of dateObj is always "Invalid Date". If I remove the "AM" from the string it parses correctly. If I try this online tester for the same code, the output is
NaN-NaN-NaN NaN:NaN PM
Like with my dev environment, if I remove the AM, it's fine.
Any ideas?
EDIT: Working on Chrome and not Firefox...

Issue on Firefox
If you deeply look at the implementation, you would see above day string going through the Day constructor: new Day('2021-02-05 12:00 AM'). Unfortunately FF doesn't support this support this day string format, but Chrome does.
Best approach
The dayjs documentation mentions:
For consistent results parsing anything other than ISO 8601 strings, you should use String + Format.
If you're still keen to use above format, you would have to use a plugin as mentioned here
Basically, you have to change as below to work in all browsers:
import customParseFormat from 'dayjs/plugin/customParseFormat'
import dayjs from "dayjs"
dayjs.extend(customParseFormat)
const yourDate = dayjs('2021-02-05 12:00 AM', 'YYYY-MM-DD HH:mm A')

Related

Comparing a moment.js obect to a timestamp from JSON response

I am trying to compare a moment object (30 days ago) to a given timestamp. Both isBefore and isAfter are returning false. Im not sure where i'm going wrong?
var startdate = moment.utc().subtract(30,'days')
var RequestedDate = moment.utc('14/12/2021, 11:26')
var isbefore = startdate.isBefore(RequestedDate)
var isafter = startdate.isAfter(RequestedDate)
console.log(isafter)
console.log(isbefore)
The requested date is not in the right format, based on the error emitted in a fiddle of your code:
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. Please refer to http://momentjs.com/guides/#/warnings/js-date/ for more info.
If you're able to use the "Date + Format" constructor, then you can parse something like this:
var RequestedDate = moment.utc('14/12/2021, 11:26', 'D/M/Y, H:m', true)
// "Tue Dec 14 2021 11:26:00 GMT+0000"
Note the use of strict mode, as in the docs:
You may get unexpected results when parsing both date and time. The below example may not parse as you expect:
moment('24/12/2019 09:15:00', "DD MM YYYY hh:mm:ss");

How to format ISO date in React-Native

I am getting date data in this format from my API:
"2018-12-26T05:00:29"
however I need to display this in the application front end in a different format like this:
"Monday, Nov 26 at 10:00 am"
How can I achieve this in react-native?
Consider using a third-party library like momentjs for advanced date parsing and formatting. Using moment, you can format the date string as required via the following pattern:
// dddd for full week day, MMM for abreviated month, DD for date, etc
moment(inputDate).format("dddd, MMM DD at HH:mm a")
The momentjs library works well with react-native and can be easily installed by:
npm install moment --save
and imported into your project:
import moment from 'moment';
Here's a snippet demonstrating the pattern shown above:
var inputDate = "2018-12-26T05:00:29";
var outputDate = moment(inputDate).format("dddd, MMM DD at HH:mm a");
console.log(outputDate);
<script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.23.0/moment.min.js"></script>
While Moment.js can resolve this issue quickly, it's however a pretty big library to use for a single use case. I recommend using date-fns instead. It's lite.
I come out of this thanks to https://github.com/date-fns/date-fns/issues/376#issuecomment-353871093.
Despite the solution, I did some perfection on Date Field Symbol. You may need to use dd instead of DD / yyyy instead of YYYY for formatting days of the month / for formatting years.
Read the doc here: https://github.com/date-fns/date-fns/blob/master/docs/unicodeTokens.md

MomentJS: how to parse dates in MM/DD/YYYY & DD/MM/YYYY

How can i use moment.js in both: Australia & USA time formats?
For example:
07/08/2017 - is good for both time formats, but!
30/08/2017 - is invalid for moment.js, but i can have such dateTime
You can check it here:
http://jsfiddle.net/rLjQx/2135/
The parser is assuming that digits of the form XX-XX-XXXX are representing DD-MM-YYYY. If you'd like it to accept MM-DD-YYYY then you need to specify this.
eg var now2 = moment('08/30/2017', 'MM-DD-YYYY').format('MMM DD h:mm A');
You can also specify an array of different formats that you'd like it to accept so that it will recognise both:
var now2 = moment('08/30/2017', ['DD-MM-YYYY', 'MM-DD-YYYY']).format('MMM DD h:mm A');
Specify the format via a second parameter to the moment call
var now2 = moment('30/08/2017', 'DD/MM/YYYY').format('MMM DD h:mm A');
Otherwise there is no way for moment to know
Related docs here: https://momentjs.com/docs/#/parsing/string-format/
Corrected fiddle: http://jsfiddle.net/wu6wwsvp/
In your fiddle you are using a very old version of moment (2.2.1), I suggest to upgrade it to lastest one (2.18.1).
Using a newer version, you will have a Deprecation Warning in your console:
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.
Following the link (and moment(String) docs) you will discover that you have to specify format to parse you string correctly.
As Billy Reilly suggested you can use moment(String, String[]) parsing function. Please remeber that:
Starting in version 2.3.0, Moment uses some simple heuristics to determine which format to use. In order:
Prefer formats resulting in valid dates over invalid ones.
Prefer formats that parse more of the string than less and use more of the format than less, i.e. prefer stricter parsing.
Prefer formats earlier in the array than later.
So the way 07/08/2017 will be interpreted depends on the order of the format in array of formats parameter.
Here a snippet with some examples:
var now = moment('30/08/2017', ['MM/DD/YYYY','DD/MM/YYYY']);
var now2 = moment('08/30/2017', ['MM/DD/YYYY','DD/MM/YYYY']);
var now3 = moment('07/08/2017', ['MM/DD/YYYY','DD/MM/YYYY']);
console.log(now.format('MMM DD h:mm A')); // Aug 30 12:00 AM
console.log(now2.format('MMM DD h:mm A'));// Aug 30 12:00 AM
console.log(now3.format('MMM DD h:mm A'));// Jul 08 12:00 AM
var now4 = moment('30/08/2017', ['DD/MM/YYYY','MM/DD/YYYY']);
var now5 = moment('08/30/2017', ['DD/MM/YYYY','MM/DD/YYYY']);
var now6 = moment('07/08/2017', ['DD/MM/YYYY','MM/DD/YYYY']);
console.log(now4.format('MMM DD h:mm A')); // Aug 30 12:00 AM
console.log(now5.format('MMM DD h:mm A')); // Aug 30 12:00 AM
console.log(now6.format('MMM DD h:mm A')); // Aug 07 12:00 AM
<script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.18.1/moment.min.js"></script>

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

How can I set up a correct format while doing new Date() in jQuery?

I have a date in a following format:
12/11/2015 07:12 PM
In jQuery I'm doing:
var parsedDate2 = new Date(date);
alert(parsedDate2);
And that prints me:
Fri Dec 11 2015 07:12:00 GMT+0100 (Central European Standard Time)
and that almost works correctly, mostly because in my example (12/11/2015 07:12 PM) the format is DD/MM and not MM/DD. However, jQuery treats it as the month is first. That's a problem, because when I chose as input:
19/11/2015 07:17 PM <--- (19th of November)
I'm getting:
Invalid date
So how can I set up the correct format here with the day before the month?
Ugly, but it work, with JS only :
a = "12/11/2015 07:12 PM";
b = a.split(' ');
c = b[0].split('/');
bad = new Date(a);
alert('bad : '+bad);
good = new Date(c[1]+'/'+c[0]+'/'+c[2]+' '+b[1]+' '+b[2]);
alert('good : '+good);
The other way is to use Moment.js parsing tool
Think that you should use more specialized and focused library along with JQuery, for me the best one is Moment.js - it has all and more than needed to date-time parsing and formatting and doesn't do something else.
Also, there are some other alternatives, like date.js and globalize.js
It's in the form of mm/dd/yyyy. Try 11/19/2015 07:17 PM. Sadly, jQuery doesn't know which format you're using and so, uses the deafult one.
Unfortunately, the Javascript Date system isn't very malleable when it comes to adding date formats. Here is a reference from Mozilla. I think wierdpanda has the right idea, write a function that accepts your date format, reformats it before feeding it to new Date(), and returns the result. Use this in place of where you have new Date(), and all should be good.

Categories