I am allowing the user to add a date manually in the date field.
If the user enters the date as 1/1/13 I am expecting a result as 01/01/2013.
This is what I am using.
Code:
moment("1/1/13").format('MM/DD/YYYY')
In chrome it is working fine but not working in FF and IE it shows 01/01/1913 instead of 01/01/2013.
Fiddle
You need to give moment the format of the data it's parsing, using moment(string, string). In fact, if you look in your web console, moment is telling you that:
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.
So:
moment("1/1/13", "M/D/YY").format("MM/DD/YYYY");
// ^^^^^^^^^^----- the format to parse with
...assuming the date is in month/day/year order (since that's what you're outputting).
Example (I've changed the date slightly so we can tell days from months):
console.log(moment("1/2/13", "M/D/YY").format("MM/DD/YYYY"));
<script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.14.1/moment.min.js"></script>
In a comment you've said:
I am allowing them to add mm/dd/yyyy and mm/dd/yy format. this is not working for 1/1/1999
See the docs linked above, if you want to support a variable number of digits in the year, use YYYY for the year:
console.log(moment("1/2/13", "M/D/YYYY").format("MM/DD/YYYY"));
console.log(moment("1/2/1999", "M/D/YYYY").format("MM/DD/YYYY"));
<script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.14.1/moment.min.js"></script>
This is because Moment.js uses the Date object when creating a new moment, and unfortunately that works differently in Firefox and Chrome.
To test it simply try creating a new date in both browsers.
new Date('1/1/13');
Frankly, I am surprised that Chrome interprets this as 2013. To be safe and cross-browser compliant, just write out the full year. If you are getting this from an outside source, you should simply be able to parse it and reformat it to a safer shortened ISO format like so:
dateString.replace(/^(\d\d?)\/(\d\d?)\/(\d\d{2,4})$/, (day, month, year) => {
day = day.length === 1 ? '0' + day : day;
month = month.length === 1 ? '0' + month : month;
year = year.length === 2 ? '20' + year : year;
if (year.length === 3) {
throw new Error('Invalid date format. Year must either be 2 or 4 characters long.);
}
return [day, '-', month, '-', year].join('');
};
It's working perfectly in Chrome and Mozilla
moment(`${day}/${month}/${year}`, "DD/MMM/YYYY").format("MMMM/DD/YYYY");
//January/01/2021
Related
This question already has answers here:
Where can I find documentation on formatting a date in JavaScript?
(39 answers)
How do I format a date in JavaScript?
(68 answers)
Closed 6 years ago.
I'm using an API to call a date from a post.
Dates are returned in ISO 8601 format :
2015-11-09T10:46:15.097Z
I want my dates to be formatted like this :
09/11/2015
Then, later, I want to insert them into my HTML, like this :
$(data).each(function(){
var html = '<randomhtml> '+this.created_at+' <randomhtml>
$('#stream').append(html);
});
Does anyone know how I can change my date to right format?
The easiest would be to just work with the string
$(data).each(function(){
var date = this.created_at.split('T') // split on the "T" -> ["2015-11-09", "10:..."]
.shift() // get the first part -> "2015-11-09"
.split('-') // split again on "-" -> ["2015", "11", "09"]
.reverse() // reverse the array -> ["09", "11", "2015"]
.join('/') // join with "/" -> "09/11/2015"
var html = '<randomhtml> ' + date + ' <randomhtml>';
$('#stream').append(html);
});
As it's a UTC date, just passing it do new Date() would add the difference of the timezone, and not always output the correct date.
If you need to validate the date, there are regexes for checking valid UTC dates.
this can be solve your problem
var date = new Date('2015-11-09T10:46:15.097Z');
alert((date.getMonth() + 1) + '/' + date.getDate() + '/' + date.getFullYear());
output will be "09/11/2015"
For date manipulation momentjs library is very useful.
If you want to make date format dependent on users country you can additionally use formatjs.
All browsers
The most reliable way to format a date with the source format you're using, is to apply the following steps :
Use your time string as input for new Date()
Use .getDate(), .getMonth() and .getFullYear() to get respectively the day, month and year
Paste the pieces together according to your target format
The format function below shows you the optimal way to combine those four steps :
var date = '2015-11-09T10:46:15.097Z';
function format(input) {
var date = new Date(input);
return [
("0" + date.getDate()).slice(-2),
("0" + (date.getMonth()+1)).slice(-2),
date.getFullYear()
].join('/');
}
document.body.innerHTML = format(date); // OUTPUT : 09/11/2015
(See also this Fiddle).
Note
While this approach does work in all browsers, you'll need an additional step before new Date(input) to parse your ISO 8601 format if you need to support browsers as old as IE8--. See the accepted answer at Javascript JSON Date parse in IE7/IE8 returns NaN for a function that does exactly that.
Modern browsers only
You can also use the built-in .toLocaleDateString method to do the formatting for you. You just need pass along the proper locale and options to match the right format, which unfortunately is only supported by modern browsers (*) :
var date = '2015-11-09T10:46:15.097Z';
function format(input) {
return new Date(input).toLocaleDateString('en-GB', {
year: 'numeric',
month: '2-digit',
day: '2-digit'
});
}
document.body.innerHTML = format(date); // OUTPUT : 09/11/2015
(See also this Fiddle).
(*) According to the MDN, "Modern browsers" means Chrome 24+, Firefox 29+, IE11, Edge12+, Opera 15+ & Safari nightly build
The simplest and most reliable way to reformat a date string is to just reformat the string. So use split (or match) to get the values and return them in the order you want, ignoring the bits you don't need, e.g.:
function isoToDMY(s) {
var b = s.split(/\D/);
return b[2] + '/' + b[1] + '/' + b[0];
}
document.write(isoToDMY('2015-11-09T10:46:15.097Z'));
If you want the output date to also consider the host system time zone (e.g. 2015-11-09T20:46:15Z in a timezone that is UTC+0530 will be 2015-11-10T02:16:15Z)), then you should manually parse it to a Date object and then get year, month and day values.
A library can help with parsing, but a function to parse and validate the values is only a few lines.
If you take the following:
var s = "2/8888/2016";
var d = new Date(s);
alert(d);
In Chrome, you'll get:
Invalid Date
But in IE and Firefox, you'll get:
Fri Jun 01 2040 00:00:00 GMT-0500 (Central Daylight Time)
It appears to be just adding 8888 days to Feb 01. Instead, I would expect the date to be considered invalid. Is there a way I can make FireFox and IE think this date string is invalid?
Short answer:
It's a misbehaviuor of the browsers you're mentioning.
You have to check date is in correct format on your own. But it's quite trivial, I suggest this approach:
Split the date in year y, month m, day d and create the Date object:
var date = new Date( y, m - 1, d ); // note that month is 0 based
Then compare the original values with the logical values obtained using the Date methods:
var isValid = date.getDate() == d &&
date.getMonth() == m-1 &&
date.getFullYear() == y;
Before doing all of this you may want to check if the date string is valid for any browser:
Detecting an "invalid date" Date instance in JavaScript
Long answer:
Firefox (and IE) accepting "2/8888/2016" as a correct string sate format seem to be a bug / misbehaviour.
In fact according to ECMAScript 2015 Language Specification when Date() is invoked with a single string argument should behave just as Date.parse()
http://www.ecma-international.org/ecma-262/6.0/#sec-date-value
The latter
attempts to parse the format of the String according to the rules (including extended years) called out in Date Time String Format (20.3.1.16)
..that is specified here
http://www.ecma-international.org/ecma-262/6.0/#sec-date-time-string-format
where you can read
The format is as follows: YYYY-MM-DDTHH:mm:ss.sssZ
[...]
MM is the month of the year from 01 (January) to 12 (December).
DD is the day of the month from 01 to 31.
It seems that Firefox is interpreting the string value as when Date() is invoked with multiple arguments.
From
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date
Note: Where Date is called as a constructor with more than one argument, if values are greater than their logical range (e.g. 13 is provided as the month value or 70 for the minute value), the adjacent value will be adjusted. E.g. new Date(2013, 13, 1) is equivalent to new Date(2014, 1, 1), both create a date for 2014-02-01 (note that the month is 0-based). Similarly for other values: new Date(2013, 2, 1, 0, 70) is equivalent to new Date(2013, 2, 1, 1, 10) which both create a date for 2013-03-01T01:10:00.
This may explain how "2/8888/2016" turns into 2040-05-31T22:00:00.000Z
There's no way to make IE and FF think it's invalid, except:
you could change their javascript implementations
you use a library instead to deal with that.
We can also expect that Javascript, as a language, evolves and we can cross our fingers that browsers decide to follow a more strict specification. The problem of course is that every "fix" must be also backward compatible with previous versions of the language (does not happen always, Perl for example).
So the best thing by now is to use some library just like momentjs as suggested by Derek in the post comments.
You have stumbled across yet another reason why you should manually parse date strings.
When Date is provided a single string argument, it is treated as a date string and parsed according to the rules in Date.parse. The rules there first attempt to parse it as an ISO 8601 format string. If that doesn't work, it may fall back to any parsing algorithm it wants.
In the case of "2/8888/2016", browsers will first attempt to parse it as an ISO format and fail. It seems from experimentation that IE and Firefox determine that the string is in month/day/year format and effectively call the Date constructor with:
new Date(2016,1,8888);
However, other browsers may attempt to validate the values and decide that 8888 is not a valid date or month, so return an invalid date. Both responses are compliant with ECMA-262.
The best advice is to always manually parse date strings (a library can help, but generally isn't necessary as a bespoke parse function with validation is 3 lines of code) then you can be certain of consistent results in any browser or host environment.
I have this very simple function that doesnt work on Firefox or IE. Just wondering if you have some insight.
function compareDates(obj, fecha){
var date1 = new Date( Date.parse(obj.value.replace(/-/g, " ")) );
var date2 = new Date( Date.parse(fecha.value.replace(/-/g, " ")) );
if(date1 < date2){
alert("Invalid Date");
}
}
This function receives a 10-JUL-13 and a 20-JUL-13, for examples.
In IE, I don't get the alert, in Chrome, I do get the alert. Please see http://jsfiddle.net/ZDtVv/
Date.parse requires an ISO date, which requires the full year. Chrome and Firefox try to figure it out for you, you shouldn't rely on that.
// This works
compareDates({value: '10-JUL-2013'}, {value: '20-JUL-2013'})
See http://jsfiddle.net/ZDtVv/1/
Those date strings are not valid date strings, so you get Date objects that have NaN as their actual timestamp. And NaN < NaN tests false.
Per spec, behavior for invalid date strings is undefined; a JavaScript implementation can turn them into NaN or use whatever heuristics it wants to for parsing them. For example, those dates could be year 13 or year 1913 or year 1413 and those would all be valid behaviors per spec.
Please correct or explain how my over-simplification is incorrect as I am not a JavaScript expert.
But I just need to know if an object is a valid date. This will only come from user input (ie, text box).
var is_valid_date = function(date) {
try {
var d = new Date(date);
return true;
}
catch(e) {
return false;
}
}
YOU have to decide what form of dates you want to accept.
Then, once you know what forms you want to accept, you can then check the spec for new Date(str) or date.parse() on MDN and see if it supports exactly what you want and if it does the right things on error conditions (it probably will not). If not, then you will have to do some manual parsing.
If you want further help from us, you will need to specify what forms of date you want to accept.
There are also some browser differences as javascript has moved to support additional date formats and earlier browsers had some inconstencies between them which all means you'll want to build yourself a simple test script with a bunch of legal and illegal date format strings and see if your validity detection does what you want in several browsers. This isn't rocket science to get it right, but it's not trivial either and requires some work unless you only want to accept what the original date object supported (which is unlikely).
If this were my code, I'd probably decide that it's far less work to do manual parsing of your desired input format that you know with 100% certainty will work in all browsers because it's your own manual parsing. I'd probably use a regex to parse the date and then convert each component to a number and check each component for validity. You can then feed those numeric components to the Date constructor to create the Date object.
If you can tell by now, the built-in date class isn't very useful for user entered input. If you're willing to use a library for this, the date.js library has a ton of useful functionality in this regard.
Here's an example of a manual parsing function that accepts these US formats:
mm-dd-yyyy
mm dd yyyy
mm/dd/yyyy
JS Code:
function checkDate(str) {
var matches = str.match(/(\d{1,2})[- \/](\d{1,2})[- \/](\d{4})/);
if (!matches) return;
// parse each piece and see if it makes a valid date object
var month = parseInt(matches[1], 10);
var day = parseInt(matches[2], 10);
var year = parseInt(matches[3], 10);
var date = new Date(year, month - 1, day);
if (!date || !date.getTime()) return;
// make sure we have no funny rollovers that the date object sometimes accepts
// month > 12, day > what's allowed for the month
if (date.getMonth() + 1 != month ||
date.getFullYear() != year ||
date.getDate() != day) {
return;
}
return(date);
}
And a demo with some test cases: http://jsfiddle.net/jfriend00/xZmBY/
If you want the Euro format, it's a trivial matter to switch the code to that. In either case, you have to decide which format you accept, code for it and then communicate to the user which format is required. If you think this is messy, then perhaps you will see why so many sites use a date calendar picker that doesn't have this complexity.
Please correct or explain how my over-simplification is incorrect as I am not a JavaScript expert.
But I just need to know if an object is a valid date. This will only come from user input (ie, text box).
Here's why it's an oversimplification.
First of all, it sounds like you really want to check the validity of a string representation of a Date object. This is not particularly useful by itself, because you are going to want to use the date for something in your script, send it to the server, etc.
If you want to use the date in your script, there are caveats.
new Date('2020-10-10') // Fri Oct 09 2020 20:00:00 GMT-0400 (EDT)
If you want to pass it to the server, you'll need to do more than just check validity– you'll need to use a format that your server side code can interpret.
If that's the case, you could consider normalizing the string into a format of your choice. You'd want to be able to create equivalent dates from the normalized strings in both your client and server side code. For simplicity, the format can be human-readable (not a timestamp), and you can replace the value of the text input with the normalized string.
Checking the validity of the string can simply be a part of normalization... have the function return false or an empty string if the input was bad, don't change the text input's value, and instead show a message indicating that the value is invalid:
// assume `birthday` is a text input.
birthday.onblur = function() {
var dateString = normalizeDate(birthday.value);
if (dateString) {
validator.style.display = 'none';
birthday.value = dateString;
} else {
validator.style.display = 'block';
}
};
Here's an example of what the normalizeDate function might look like. This example uses the format 'yyyy-mm-dd', you can change it to suit your needs.
function normalizeDate(dateString) {
// If it's not at least 6 characters long (8/8/88), give up.
if (dateString.length && dateString.length < 6) {
return '';
}
var date = new Date(dateString),
month, day;
// If input format was in UTC time, adjust it to local.
if (date.getHours() || date.getMinutes()) {
date.setMinutes(date.getTimezoneOffset());
}
month = date.getMonth() + 1;
day = date.getDate();
// Return empty string for invalid dates
if (!day) {
return '';
}
// Return the normalized string.
return date.getFullYear() + '-' +
(month > 9 ? '' : '0') + month + '-' +
(day > 9 ? '' : '0') + day;
}
Here's the obligatory live demo.
new Date() doesn't throw an exception if month>12 for example, you can use Date.parse() and test the returned value with isNaN()
alert(new Date('2010-11-29'));
chrome, ff doesn't have problems with this, but safari cries "invalid date". Why ?
edit : ok, as per the comments below, I used string parsing and tried this :
alert(new Date('11-29-2010')); //doesn't work in safari
alert(new Date('29-11-2010')); //doesn't work in safari
alert(new Date('2010-29-11')); //doesn't work in safari
edit Mar 22 2018 : Seems like people are still landing here - Today, I would use moment or date-fns and be done with it. Date-fns is very much pain free and light as well.
For me implementing a new library just because Safari cannot do it correctly is too much and a regex is overkill.
Here is the oneliner:
console.log (new Date('2011-04-12'.replace(/-/g, "/")));
The pattern yyyy-MM-dd isn't an officially supported format for Date constructor. Firefox seems to support it, but don't count on other browsers doing the same.
Here are some supported strings:
MM-dd-yyyy
yyyy/MM/dd
MM/dd/yyyy
MMMM dd, yyyy
MMM dd, yyyy
DateJS seems like a good library for parsing non standard date formats.
Edit: just checked ECMA-262 standard. Quoting from section 15.9.1.15:
Date Time String Format
ECMAScript defines a string
interchange format for date-times
based upon a simplification of the ISO
8601 Extended Format. The format is
as follows: YYYY-MM-DDTHH:mm:ss.sssZ
Where the fields are as follows:
YYYY is the decimal digits of the year in the Gregorian calendar.
"-" (hyphon) appears literally twice in the string.
MM is the month of the year from 01 (January) to 12 (December).
DD is the day of the month from 01 to 31.
"T" appears literally in the string, to indicate the beginning of
the time element.
HH is the number of complete hours that have passed since midnight as two
decimal digits.
":" (colon) appears literally twice in the string.
mm is the number of complete minutes since the start of the hour as
two decimal digits.
ss is the number of complete seconds since the start of the minute
as two decimal digits.
"." (dot) appears literally in the string.
sss is the number of complete milliseconds since the start of the
second as three decimal digits. Both
the "." and the milliseconds field may
be omitted.
Z is the time zone offset specified as "Z" (for UTC) or either "+" or "-"
followed by a time expression hh:mm
This format includes date-only forms:
YYYY
YYYY-MM
YYYY-MM-DD
It also includes time-only forms with
an optional time zone offset appended:
THH:mm
THH:mm:ss
THH:mm:ss.sss
Also included are "date-times" which
may be any combination of the above.
So, it seems that YYYY-MM-DD is included in the standard, but for some reason, Safari doesn't support it.
Update: after looking at datejs documentation, using it, your problem should be solved using code like this:
var myDate1 = Date.parseExact("29-11-2010", "dd-MM-yyyy");
var myDate2 = Date.parseExact("11-29-2010", "MM-dd-yyyy");
var myDate3 = Date.parseExact("2010-11-29", "yyyy-MM-dd");
var myDate4 = Date.parseExact("2010-29-11", "yyyy-dd-MM");
I was facing a similar issue. Date.Parse("DATESTRING") was working on Chrome (Version 59.0.3071.115 ) but not of Safari (Version 10.1.1 (11603.2.5) )
Safari:
Date.parse("2017-01-22 11:57:00")
NaN
Chrome:
Date.parse("2017-01-22 11:57:00")
1485115020000
The solution that worked for me was replacing the space in the dateString with "T". ( example : dateString.replace(/ /g,"T") )
Safari:
Date.parse("2017-01-22T11:57:00")
1485086220000
Chrome:
Date.parse("2017-01-22T11:57:00")
1485115020000
Note that the response from Safari browser is 8hrs (28800000ms) less than the response seen in Chrome browser because Safari returned the response in local TZ (which is 8hrs behind UTC)
To get both the times in same TZ
Safari:
Date.parse("2017-01-22T11:57:00Z")
1485086220000
Chrome:
Date.parse("2017-01-22T11:57:00Z")
1485086220000
I use moment to solve the problem.
For example
var startDate = moment('2015-07-06 08:00', 'YYYY-MM-DD HH:mm').toDate();
To have a solution working on most browsers, you should create your date-object with this format
(year, month, date, hours, minutes, seconds, ms)
e.g.:
dateObj = new Date(2014, 6, 25); //UTC time / Months are mapped from 0 to 11
alert(dateObj.getTime()); //gives back timestamp in ms
works fine with IE, FF, Chrome and Safari. Even older versions.
IE Dev Center: Date Object (JavaScript)
Mozilla Dev Network: Date
convert string to Date fromat (you have to know server timezone)
new Date('2015-06-16 11:00:00'.replace(/\s+/g, 'T').concat('.000+08:00')).getTime()
where +08:00 = timeZone from server
I had the same issue.Then I used moment.Js.Problem has vanished.
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.
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.
e.g.
var date= moment(String);
For people using date-fns we can parseISO date and use it to format
Invalid
import _format from 'date-fns/format';
export function formatDate(date: string, format: string): string {
return _format(new Date(date), format);
}
This function on safari throw error with Invalid date.
Solution
To fix it we should use:
import _format from 'date-fns/format';
import _parseISO from 'date-fns/parseISO';
export function formatDate(date: string, format: string): string {
return _format(_parseISO(date), format);
}
Though you might hope that browsers would support ISO 8601 (or date-only subsets thereof), this is not the case. All browsers that I know of (at least in the US/English locales I use) are able to parse the horrible US MM/DD/YYYY format.
If you already have the parts of the date, you might instead want to try using Date.UTC(). If you don't, but you must use the YYYY-MM-DD format, I suggest using a regular expression to parse the pieces you know and then pass them to Date.UTC().
How about hijack Date with fix-date? No dependencies, min + gzip = 280 B
I am also facing the same problem in Safari Browser
var date = new Date("2011-02-07");
console.log(date) // IE you get ‘NaN’ returned and in Safari you get ‘Invalid Date’
Here the solution:
var d = new Date(2011, 01, 07); // yyyy, mm-1, dd
var d = new Date(2011, 01, 07, 11, 05, 00); // yyyy, mm-1, dd, hh, mm, ss
var d = new Date("02/07/2011"); // "mm/dd/yyyy"
var d = new Date("02/07/2011 11:05:00"); // "mm/dd/yyyy hh:mm:ss"
var d = new Date(1297076700000); // milliseconds
var d = new Date("Mon Feb 07 2011 11:05:00 GMT"); // ""Day Mon dd yyyy hh:mm:ss GMT/UTC
Use the below format, it would work on all the browsers
var year = 2016;
var month = 02; // month varies from 0-11 (Jan-Dec)
var day = 23;
month = month<10?"0"+month:month; // to ensure YYYY-MM-DD format
day = day<10?"0"+day:day;
dateObj = new Date(year+"-"+month+"-"+day);
alert(dateObj);
//Your output would look like this "Wed Mar 23 2016 00:00:00 GMT+0530 (IST)"
//Note this would be in the current timezone in this case denoted by IST, to convert to UTC timezone you can include
alert(dateObj.toUTCSting);
//Your output now would like this "Tue, 22 Mar 2016 18:30:00 GMT"
Note that now the dateObj shows the time in GMT format, also note that the date and time have been changed correspondingly.
The "toUTCSting" function retrieves the corresponding time at the Greenwich meridian. This it accomplishes by establishing the time difference between your current timezone to the Greenwich Meridian timezone.
In the above case the time before conversion was 00:00 hours and minutes on the 23rd of March in the year 2016. And after conversion from GMT+0530 (IST) hours to GMT (it basically subtracts 5.30 hours from the given timestamp in this case) the time reflects 18.30 hours on the 22nd of March in the year 2016 (exactly 5.30 hours behind the first time).
Further to convert any date object to timestamp you can use
alert(dateObj.getTime());
//output would look something similar to this "1458671400000"
This would give you the unique timestamp of the time
Best way to do it is by using the following format:
new Date(year, month, day, hours, minutes, seconds, milliseconds)
var d = new Date(2018, 11, 24, 10, 33, 30, 0);
This is supported in all browsers and will not give you any issues.
Please note that the months are written from 0 to 11.
For me the issue was I forgot to add 0 before the single digit month or day in YYYY-MM-DD format.
What I was parsing: 2021-11-5
What it should be: 2021-11-05
So, I wrote a little utility which converts YYYY-M-D to YYYY-MM-DD i.e. 2021-1-1 to 2021-01-01:
const date = "2021-1-1"
const YYYY = date.split("-")[0];
//convert M->MM i.e. 2->02
const MM =
date.split("-")[1].length == 1
? "0" + date.split("-")[1]
: date.split("-")[1];
//convert D->DD i.e. 2->02
const DD =
date.split("-")[2].length == 1
? "0" + date.split("-")[2]
: date.split("-")[2];
// YYYY-MM-DD
const properDateString = `${YYYY + "-" + MM + "-" + DD}`;
const dateObj = new Date(properDateString);
As #nizantz previously mentioned, using Date.parse() wasn't working for me in Safari. After a bit of research, I learned that the lastDateModified property for the File object has been deprecated, and is no longer supported by Safari. Using the lastModified property of the File object resolved my issues. Sure dislike it when bad info is found online.
Thanks to all who contributed to this post that assisted me in going down the path I needed to learn about my issue. Had it not been for this info, I never would have probably figured out my root issue. Maybe this will help someone else in my similar situation.
Arriving late to the party but in our case we were getting this issue in Safari & iOS when using ES6 back tick instead of String() to type cast
This was giving 'invalid date' error
const dateString = '2011-11-18';
const dateObj = new Date(`${dateString}`);
But this works
const dateObj = new Date(String(dateString));
In my case, it wasn't the formatting, it was because in my backend Node.js Model, I was defining the database variable as a String instead of a Date.
My backend Node Database Model said:
starttime:{
type: String,
}
instead of the correct:
starttime:{
type: Date,
}
The same problem facing in Safari and it was solved by inserting this in web page
<script src="https://cdn.polyfill.io/v2/polyfill.min.js?features=Intl.~locale.en"></script>
Hope it will work also your case too
Thanks
This will not work alert(new Date('2010-11-29')); safari have some weird/strict way of processing date format alert(new Date(String('2010-11-29'))); try like this.
(Or)
Using Moment js will solve the issue though, After ios 14 the safari gets even weird
Try this alert(moment(String("2015-12-31 00:00:00")));
Moment JS
use the format 'mm/dd/yyyy'. For example :- new Date('02/28/2015'). It works well in all browsers.
This is not the best solution, although I simply catch the error and send back current date. I personally feel like not solving Safari issues, if users want to use a sh*t non-standards compliant browser - they have to live with quirks.
function safeDate(dateString = "") {
let date = new Date();
try {
if (Date.parse(dateString)) {
date = new Date(Date.parse(dateString))
}
} catch (error) {
// do nothing.
}
return date;
}
I'd suggest having your backend send ISO dates.