Troubleshooting RTZ2 after Microsoft Update KB2998527

After the release of the update mentioned above, many developers have encountered problems. At the moment, they tried to fix the problem somehow in Chrome, but in IE10 (Document mode = “Standarts”) everything works fine, but in older browsers and IE compatibility modes all work with dates fell apart.

It so happened that due to technical limitations I have to support the work of the applications I am developing in IE8-9-10 and Chrome. In addition, I use the momentjs library to work with dates .

Since the release date was around the corner, then, searching the open spaces of the World Wide Web for a solution to the problem and not finding it, I decided that sooner or later browser developers would solve this problem and I would not have to change anything. But the release is getting closer, and there was no solution either.

And now it's time to solve this problem yourself.

I will briefly describe the main problems in the form of a table (unexpected results are crossed out ):

IE10 (IE8 standarts)IE9 (all document modes)IE10 (IE10 standarts)Chrome 38.0.2125.122 m
new Date (2014, 0, 1)Tue Dec 31 23:00:00 UTC + 0300 2013Wed Jan 1 00:00:00 UTC + 0300 2014Wed Jan 1 00:00:00 UTC + 0400 2014Wed Jan 01 2014 01:00:00 GMT + 0400
new Date (2015, 0, 7)Tue Jan 6 23:00:00 UTC + 0300 2015Tue Jan 6 23:00:00 UTC + 0300 2015Wed Jan 7 00:00:00 UTC + 0300 2015Wed Jan 07 2015 01:00:00 GMT + 0400
moment (). startOf ('year')Tue Dec 31 23:00:00 UTC + 0300 2013Wed Jan 1 00:00:00 UTC + 0300 2014Wed Jan 1 00:00:00 UTC + 0400 2014Wed Jan 01 2014 01:00:00 GMT + 0400
moment (). endOf ('year')Wed Dec 31 22:59:59 UTC + 0300 2014Wed Dec 31 23:59:59 UTC + 0300 2014Wed Dec 31 23:59:59 UTC + 0300 2014Thu Jan 01 2015 00:59:59 GMT + 0300

The first thing that came to mind was to modify the library of working with dates (momentjs) for the correct calculation of time instants and use it everywhere instead of the original Date object or find an alternative library. Looked at datejs, xdate, tzdata-javascript. But rewriting a lot of code for a “temporary” solution to problems seemed too time-consuming. All the same, the hope that the problems with the time zone will disappear with the following browser patches remains.

And then a bright thought came - to change the Date object. Let it handle problematic dates and bring them to a single view independent of the browser. Those. new Date (2014, 0, 1) should always create a date 01.01.2014 00:00 UTC + 0400, then momentjs.endOf ('year') will correctly calculate the end of the year.

How to achieve this?

The principle is this: time in UTC + 0000 is continuous and errors in the implementation of the time zone do not affect it, therefore, all manipulations with the date can be performed in UTC. And in general, ignore the work with the time zone in the browser since it does not work correctly. But this refinement should be transparent to the user (Web developer), i.e. he should still see the date in his local time zone.

Having studied the specification of the Date object , I developed the following method:

1. It is necessary to redefine the Date constructor so that it creates time in UTC.
Call the original Date object NativeDate, and the new (fixed) NewDate object.
Then NewDate (year, month, date) will actually execute the NativeDate code (NativeDate.UTC (year, month, date)).
2. The methods setTime, getTime and valueOf work with offset, that is, if described schematically, then NewDate.setTime (offset) performs NativeDate.setTime (offset + _nullOffset), and NewDate.getTime () and NewDate.valueOf () return NativeDate.getTime () -_ nullOffset. Where _nullOffset = -new NativeDate (0) .getTimezoneOffset () * 60000. This approach will ensure transparent work with zero offset (new Date (0)).
3. Setters and getters for the Date, Day, FullYear, Hours, Milliseconds, Minutes, Month, Seconds properties of the NewDate object, we make references to setters and getters of similar properties with the UTC prefix of the NativeDate object. And setters and getters with the UTC prefix for NewDate will take into account the time zone.
After completing these steps, everything worked just fine.

However, to fully support the functionality of the original Date object, it was necessary to support all the options for invoking the Date constructor, as well as the Date.parse, Date.UTC, methods and all possible ways to serialize the object into a string.

It turned out something like this: rtz2fix .

I would be very happy if someone finds problems in this solution and reports them to me.

Related Links

"Chrome that stole Christmas" ;
"New timezone - new problems . "

Also popular now: