While creating/testing a date adapter in my Angular project I ran into this issue. I think I must be missing some convention, but when changing the month to a single digit like 2 (for February) rather than 02, I get a different day.
Date.parse is giving two different outputs based on that different as pictured below. Any thoughts?
According to the documentation:
The ECMAScript specification states: If the String does not conform to the standard format the function may fall back to any implementation–specific heuristics or implementation–specific parsing algorithm.
Here, the second string does not match the expected format, and Chrome does something with it.
If you test it with Firefox, the same date is returned, so it's a Chrome "issue".
You can try to read V8's source code to understand why you get this and how it is actually implemented.
This isn't a lot of help, but I don't think you'll find anything without getting to the bottom of V8.
Related
I read in the MDN documentation that:
toLocaleTimeString() without arguments depends on the
implementation,the default locale, and the default time zone
What does this mean exactly?
And I tried the following code in both Chrome(Version 87.0.4280.88) and Safari browser(Version 14.0).
new Date().toLocaleTimeString()
in Chrome it gives output as
16:57:37
whereas in Safari it gives output as
4:57:37 PM
With regards to the above example can someone explain how the implementation is changing from one browser to another, and why is it so?
Edit:
All this was done using MAC, I tried changing preferred language under Setting -> "Language and Region" to English(US) it was English(India) before, as soon as I did that change and restarted chrome the result became.
4:57:37 PM
But for Safari without doing this change it was able to show in 12 hour format, what was the reason for that?
The specification for toLocaleTimeString states:
This function returns a String value. The contents of the String are implementation-defined, but are intended to represent the “time” portion of the Date in the current time zone in a convenient, human-readable form that corresponds to the conventions of the host environment's current locale.
with the definition of implementation-defined being:
An implementation-defined facility is one that defers its definition
to an external source without further qualification. This
specification does not make any recommendations for particular
behaviours, and conforming implementations are free to choose any
behaviour within the constraints put forth by this specification.
Therefore browsers are free to implement this feature as they see fit.
I am creating a new date toISOString -
new Date(03-13-2016 00:00).toISOString();
This works fine in IE and Chrome however NOT in FireFox.
I have tried to modify the string slightly like -
new Date(03-13-2016T00:00:00Z).toISOString();
However this also failed. How can I achieve the desired result to work across all browsers?
2016-03-13T00:00:00.000Z
PS I am aware I start with a string then try and create a string with the toISOString - reason being this handles timezone offset to UTC in one line which is required.
When you pass a string to the Date constructor, it internally calls Date.parse to attempt to get a valid date from it. This first checks to see if it is one of the Date Time formats in the specification. If not (and both "03-13-2016 00:00" and "03-13-2016T00:00:00Z" aren't), the parse specification goes on to say:
If the String does not conform to that format the function may fall back to any implementation-specific heuristics or implementation-specific date formats. Unrecognizable Strings or dates containing illegal element values in the format String shall cause Date.parse to return NaN.
In this case, it seems both IE and Chrome have code in place that allows it to be correctly parsed, while Firefox doesn't. The only way you're really going to fix this is to have a string that conforms to the specification, or to call the constructor with individual date/time component parts.
If you don't mind pulling a library in or need to work with dates more often, use moment.js which has some very convenient date and time methods and is cross browser compatible.
Your string could then be converted to an ISO String like:
moment('03-13-2016 00:00', 'MM-DD-YYYY HH:mm').format();
So I was wondering if the javascript function Date() recently changed for Firefox or even other browsers.
At first I would get a date output like this: Mon Apr 13 2015 22:18:08 GMT+0200 (West-Europa (zomertijd))
But now it's outputting something like this: 2015-04-13T20:15:18.322Z
I had a script that was depending on the first format so it broke while nothing changed in my code. That's why I started investigating and found this as the problem.
I was wondering what's up with this. (I'm not asking for a formatting solution, just wondering why it's formatted like this)
Update 1: figured it might be useful to add version numbers of the browsers I tested (all with the same result).
Firefox developers edition: 39.0a2 (2015-04-07)
Iceweasel 31.4.0
Firefox 37.0.1
Update 2: Code example:
new Date();
-- output -- Date 2015-04-13T20:57:39.622Z
Turns out this is an UTC or Zulu time format. So now the question is: Why is it outputting a UTC date while it didn't do that before.
new Date() returns a date object. The console in Firefox helps you as a developer to debug things, and Mozilla may have changed the representation of an object in the console. Maybe they first just showed the date the object represented, and now they show a representation of the object that you can explore (there's a triangle ▶ that you can click on which expands the representation and shows more properties of the object).
It shouldn't matter for the behavior of your programs. When you output a date on a page, you would not directly print the object, but convert it to a string for example, which you get in the case of new Date().toString(). This behavior won't likely just change for no reason.
I am using the JavaScript Date function toLocaleDateString() to format my date to look like 8/13/2014, but for some reason when I try to send this value via an API call by doing a JSON.stringify and then AJAXing the value, IE decides to change the actual value to be ?8?/?30?/?2014.. This obviously causes errors on the back end.
Why does IE do this and how can I fix it?
Looks like it's a bug that was introduced in IE 11. IE 11 uses Unicode chars, so what you see is U+200E 'LEFT-TO-RIGHT MARK'
What you can do as a temporary solution to fix this issue is to replace that char. Like this:
console.log((new Date()).toLocaleDateString().replace(/\u200E/g, ''));
You should check out the answer here:
ToLocaleDateString() changes in IE11
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)
Although the function returns a string, it's only human-readable and is never appropriate for machine parsing. I'm not 100% sure what encoding it is for IE, but although it looks like a string, underneath it uses a different encoding.
For date formatting, you may wish to use Moment.js, or just write your own formatting function.
While trying to parse an ISO-8601 formatted string in Javascript, I noticed that it cannot parse the string when the offset lacks the minute part. E.g:
Date.parse("2014-05-16T07:28:51.148412+02")
results evaluates to NaN, whereas
Date.parse("2014-05-16T07:28:51.148412+02:00")
evaluates to 1400218131148. This was confusing me, as both NodaTime (where the string without the minutes gets generated) and Javascript seem to support ISO-8601. What is interesting is that different sources make different statements about whether the minute part is required or not: Wikipedia says it is optional whereas this document says it's not.
So what is the correct specification? Should I even file a bug for NodaTime that they don't follow the standard? And what would be a workaround? I can't seem to get NodaTime to produce the offset with minutes.
Noda Time follows the ISO 8601 specification (if you don't want to buy it, you can find draft specifications for free) correctly. However, the Date object in Javascript doesn't follow ISO 8601, but a format based on that standard.
If you look in the ECMA-262 specification (which applies to Javascript), you see that Date.parse must understand the so-called Date Time String Format. It's "based upon a simplification of the ISO 8601 Extended Format", and requires the time zone specifier, if present, to be Z, +hh:mm or -hh:mm.
See #Rhymoid's answer for information on the standards. I just add the solution that I finally took to parse ISO-8601 formatted dates in JavaScript.
There is a library called Moment.js, which is able to parse ISO-8601:
moment("2014-05-16T07:28:51.148412+02")
This returns a valid date object with the specified offset.