ToLocaleDateString() changes in IE11
The issue is that if you try to use the value programmatically to create a date, it's invalid.
...
Am I doing something wrong, or is there some other way I'm supposed to be interacting with the javascript Date?
Yes, you are doing it wrong. You shouldn't be using a function intended to format something for locale-specific human display and expect the output to be machine parsable. Any of the output of toLocaleString
, toLocaleDateString
, or toLocaleTimeString
are meant for human-readable display only. (As Bergi clarified in comments, toString
is also meant for human display, but ECMA §15.9.4.2 says it should round-trip)
You are likely getting the LTR markers because your display locale is RTL. Besides this, consider that the locale will always affect the output. Perhaps your locale uses dd/mm/yyyy formatting instead of mm/dd/yyyy formatting. Or perhaps your locale requires Asian or Arabic characters. These are all considerations when determining a display format, but are never appropriate for machine parsing.
Also consider that the ECMAScript specification does not define any particular formatting rules for the output of these methods, and different browsers will yield different results.
If the intent is anything other than to display to the user, then you should use one of these functions instead:
toISOString
will give you an ISO8601/RFC3339 formatted timestamptoGMTString
ortoUTCString
will give you an RFC822/RFC1123 formatted timestampgetTime
will give you an integer Unix Timestamp with millisecond precision
All of the above will return a UTC-based value. If you want the local time, you can either build your own string with the various accessor functions (getFullYear
, getMonth
, etc...), or you can use a library such as moment.js:
This uses moment.js to return an ISO8601 formatted local time + offset from a date:
moment(theDate).format() // ex: "2014-08-14T13:32:21-07:00"
ToLocaleDateString() workaround for IE & Chrome
Date.toLocaleString
accepts an option parameter allowing to declare how you want your output.
In your case you'll want {day: 'numeric', month:'numeric', year:'numeric'}
:
var date = new Date();firstDay = new Date(date.getFullYear(), date.getMonth() + 1, 1);firstDay = new Date(firstDay).toLocaleString('en-US', { day: 'numeric', month: 'numeric', year: 'numeric' }).replace(/[^ -~]/g,'');console.log(firstDay);
IE 11 - Date is not working
Seems it can be done like this
new Date(new Date().toLocaleDateString('en-US').replace(/[^ -~]/g,''))
Reference Answer
Internet Explorer Returning Wrong Length of String
So, I stumbled upon this post toLocaleDateString error in IE 11
It appears it is caused by the toLocaleDateString function added extra LTR and RTL characters in IE11. One of the comments gave a regex replace function that is working for me.
month.replace(/[^ -~]/g,'');
Try adding that after you perform the .toLocaleDateString()
and it should work. It worked for me.
Just another reason for us to despise IE.
Date.parse failing in IE 11 with NaN
According to MDN docs for Date.parse()
parameter:
dateString
A string representing an RFC2822 or ISO 8601 date (other formats may be used, but results may be unexpected).
Looks like Microsoft simply didn't implement the format you provided. I wouldn't use this format anyway, because it's locale dependent(might just be dd/mm/yyyy or sometimes might also fit mm/dd/yyyy).
An alternative to your solution is to use moment.js. It has a very powerful API for creating/parsing/manipulating dates. I'll show some examples on how you could use it:
//Create an instance with the current date and time
var now = moment();
//Parse the first the first argument using the format specified in the second
var specificTime = moment('5/12/2017 09:00 AM', 'DD/MM/YYYY hh:mm a');
//Compares the current date with the one specified
var beforeNow = specificTime.isBefore(now);
It offers a lot more and might help you simplify your code a great deal.
Edit:
I rewrote your code using moment.js
version 2.18.1 and it looks like this:
function parseDateCustom(date) {
return moment(date, 'YYYY-MM-DD hh:mm a');
}
var tArray = ["09:00 AM", "05:00 PM"];
var currentDate = moment().format('YYYY-MM-DD') + ' ';
var timeString1 = parseDateCustom(currentDate + tArray[0]);
var timeString2 = parseDateCustom(currentDate + tArray[1]);
var currentTimeString = parseDateCustom(currentDate + "01:18 pm");
if (timeString1.isBefore(currentTimeString) && currentTimeString.isBefore(timeString2)) {
console.log('Sucess');
} else {
console.log('Failed');
}
Is this a bug in IE 11?
Why not just to get the day from the available method from the object Date.
var day = new Date('3/4/2019').getDate();console.log(day >= 10 ? day : ("0" + day)); // We can use String.prototype.padStart(2, "0"), however, that's not available in IE11
IE's toLocaleString has strange characters in results
First, a bit of background: IE11 implemented the ECMA-402 ECMAScript Internationalization API that redefined Date.prototype.toLocaleString
(as well as toLocaleDateString
and toLocaleTimeString
) as calls to format
on Intl.DateTimeFormat
. As such, d.toLocaleString()
is equivalent to
Intl.DateTimeFormat(undefined, {
year: 'numeric',
month: 'numeric',
day: 'numeric',
hour: 'numeric',
minute: 'numeric',
second: 'numeric'
}).format(d)
You might think that this is pretty explicit but browsers are allowed a large amount of leeway with what formats they support and what characters compose the format. This is by design - with all the locales and languages around the planet, specifying this would be quite burdensome and very difficult to keep up-to-date. For this reason you cannot expect to be able to compare the results of toLocaleString
across browsers or even expect the same browser to continue giving the same result from release to release. As the underlying locale data changes (perhaps because local custom has changed, or more data is available, or better formats are added), so too will the format that is returned from this API.
The takeaway from this is that you should try not to rely on comparing the output of the toLocaleString
APIs with some static value in your application. Further, given a date d
, Date.parse(d.toLocaleString())
may work sometimes but not others depending on locale, so it's best to avoid this as well.
With that said, en-US is relatively stable and for the most part browsers do (for now) agree on what that basic format is. However, IE inserts bidirectional control characters around the date. This is by design so the output text will flow properly when concatenated with other text. This is especially important when mixing LTR and RTL content such as concatenating a formatted RTL date with LTR text.
Related Topics
Optional Chaining in JavaScript
Need to Escape a Special Character in a Jquery Selector String
Regex Using JavaScript to Return Just Numbers
Tool to Unminify/Decompress JavaScript
How to Delay a Function Call for 5 Seconds
JavaScript Convert Hsb/Hsv Color to Rgb Accurately
React Component Initialize State from Props
How to Override JavaScript's Tostring() Function to Provide Meaningful Output for Debugging
How to Check If Iframe Is Loaded or It Has a Content
React Router V6 Navigate Outside of Components
Checking If Jquery Is Loaded Using JavaScript
How to Get the Selected Text in a Textarea
How to Watch for Array Changes
Chrome, JavaScript, Window.Open in New Tab
How to Create a Jquery Plugin with Methods
How to Perform Case-Insensitive Sorting Array of String in JavaScript