📜 ⬆️ ⬇️

ISO 8601 and ECMAScript - a headache from different interpretations of standards

We are developing here some integration service with a very third-party system. The service itself works on Node.js. And everything would be fine, but only the inaccessibility of the server during garbage collection made the third-party system very unnerving.

On the eve of the new year, it was decided to make a gift to the server - to update Node.js from version 0.4.8 to 0.6.6 For a number of organizational reasons, which I don’t really want to discuss here, the update was carried out immediately on the combat system and even without regression testing .

Could something really go wrong in this situation?
')
Updated. We work on. Suddenly it turns out that in messages transmitted by a third-party system, time is shifted by 4 hours ahead. There is probably no need to talk about the business implications of such a shift.

We start to think. There is a hypothesis that if everything worked before, and suddenly stopped with the update of Node.js, it means that it is in it or in v8. Can not be, I say. To such a jamb and we first noticed - surely this is our admin screwed up. Obviously, I say, he has something wrong with the time zone settings on the server. They looked into all possible corners - no, everything is clear.

The last, the most incredible hypothesis remains - the time parsing in ISO 8601 format broke. It is in this format that the third-party system sends the time in messages. It would seem, well, what can be broken. Here comes the local time: “2011-12-30T22: 00: 00”. In a quick look in the server:

 > var d = new Date ('2011-12-30T22: 00: 00')
 undefined
 > d
 Fri, 30 Dec 2011 22:00:00 GMT
 > d.getHours ()
 2

Opanki. The server obviously lives in GMT. Not otherwise, already emigrated. Checking:

 > var d = new Date ('2011-12-30T22: 00: 00Z')
 undefined
 > d
 Fri, 30 Dec 2011 22:00:00 GMT
 > d.getHours ()
 2

In both cases, regardless of whether the time is indicated locally or GMT, it is perceived as GMT. We are looking at what Chrome will say:

 > var d = new Date ('2011-12-30T22: 00: 00')
 undefined
 > d.toString ()
 "Sat Dec 31 2011 02:00:00 GMT + 0400 (MSK)"
 > d.getHours ()
 2

But this is already unpleasant. Chrome - at the workstation. And with the time zone everything is in order.

While the developer is pulling me off with the question “When will we have a bug on Google?” I read the description of the standard. 130 francs for the official document is not, therefore, we study Wikipedia :
If you are not

We dig further.

 var d = new Date ('2011-12-30T22: 00: 00')
 undefined
 d.  getTimezoneOffset () / 60
 -four

-4 returns on all tested computers and platforms. Then a thought comes to my mind. Until now, we checked everything except Firefox and Windows. I look in FF under Windows:

 var d = new Date ('2011-12-30T22: 00: 00')
 undefined
 d.getUTCHours ()
 18
 d.getHours ()
 22

I check the same thing in Chrome under Windows:

 var d = new Date ('2011-12-30T22: 00: 00')
 undefined
 d.getUTCHours ()
 22
 d.getHours ()
 2

Wow! Does Google really have a cant? Again, an offer to write a bug report. Composing it is still too lazy, so I am starting to read manuals.

Mozilla Developer Network (MDN). Description of the Date.parse method:
If you do not specify a time zone, it is assumed

Here, the time is disassembled according to the standard, so Firefox is correct.

There is no independent documentation on v8, but there is a link to ECMAscript. Download the version 5.1 specification, on page 181 we read:
The value of an absent time zone offset is "Z".

Wow! The third-party system transmits us local time in accordance with the ISO standard, and our server interprets it as Greenwich time - in full compliance with the ECMA standard.

Just in case, I read MSDN - Microsoft has long since claimed that their JavaScript standard is the most correct, because it is ECMA. And for sure:
If you do not include a value in the Z position, UTC time is used.

Examination of the repositories showed that the very correction of the behavior of v8 was made in the wording of 8513 at the end of June 2011. However, when Mozille was asked to fix it in his room, the discussion pointed to discrepancies in ISO and ECMA 5.1 standards. As a result, there is a chance that in version 6 of the ECMA standard, time will still be dealt with correctly .

And we still had to add crutches to the code. If the time coming from the third-party system does not contain an indication of the time zone, add getTimezoneOffset to it. After the new ECMA standard comes out, in which this discrepancy will be corrected and the v8 will be updated in accordance with this standard, we will have to track this down and remove the crutches.

PS Habrayuser zerodivisi0n , which, unfortunately, has read-only rights, has taken the brunt of the events described. If someone has enough karma (or whatever is needed there) to transfer him to a more advanced state, we will both be very grateful. At the same time, he himself will be able to answer questions.

Source: https://habr.com/ru/post/135565/


All Articles