[OPEN-125] DST issue calculating Day numbers in MonthView

Report bugs for any Extensible Components

[OPEN-125] DST issue calculating Day numbers in MonthView

Postby geoffrey.mcgill » Mon Nov 15, 2010 1:47 am

Hi,

I believe there is an issue related to DST in how the Day numbers are calculated in Month View.

Here's a screen cap demonstrating the issue (notice 15-16-16-17).

http://imgur.com/cw789.jpg

To the best of my knowledge this calculation error is specifically trigger only with operating systems + browser configured with the Brazilian DST schedule. For some unfortunate reason, Brazilian DST is observed at the time 00:00:00, whereas typically DST is observed by governments at +1 or +2 hours after 00:00:00. I'll explain below why this creates a problem.

More info:

http://www.timeanddate.com/news/time/brazil-dst-start-2010.html

I don't know *where* specifically in the Calendar source the calculation error is happening but I think I can explain *what* is happening...

Take for example two Dates, the day before DST and the day of DST

Code: Select all
1. 2010-10-16 <-- Day before
2. 2010-10-17 <-- Day of, DST happens at 00:00:00 here, or you could also say midnight of 16th.


When calculating the Month View cell values, the new "day number" is calculated by adding one "day" to the previous "day". The following example uses a ISO 8061 date/time format and pseudo code (assume Brazil DST):

Code: Select all
2010-10-15T00:00:00 + "one day" = 2010-10-16T00:00:00 <-- correct
2010-10-16T00:00:00 + "one day" = 2010-10-17T00:00:00 <-- almost correct, but we forgot to "fall back" an hour for DST
[Revised]
2010-10-16T00:00:00 + "one day" = 2010-10-17T00:00:00 - "one hour" = 2010-10-16T23:00:00


With Brazil DST, "one day" is only "23 hours". Now the Date object being used to render the day "17" cell is 2010-10-16.

I've only known this problem to occur with Brazil DST, although there may be others as I haven't fully researched.

When calculating the MonthView cells "day" values, this issue can be avoided for all DST timezones (globally) by adding "26 hours" to the previous cells Date object, instead of "one day", then call .clearTime().

Not to make this problem any trickier to detect/debug, but this is a difficult one to reproduce. You need a machine configured with Brazil culture, timezone and maybe even need to travel to Brazil to test (just kidding).

Of course, I could be completely wrong about all this and the problem is related to something else.

Hope this helps. Cheers!

tl;dr When calculating successive calendar cell "day" values in JavaScript, add "26 hours" instead of "1 day" to avoid obscure DST issues.

tl;drx2 Someone should tactfully ask the the Brazilian Ministry of Mines and Energy to change their future official DST start times to 02:00:00.
geoffrey.mcgill
 
Posts: 3
Joined: Mon Nov 15, 2010 12:10 am

Re: DST related issue calculating Day numbers in MonthView

Postby geoffrey.mcgill » Mon Nov 15, 2010 1:49 am

I should add, this issue was first reported at

http://forums.ext.net/showthread.php?10475#post43079
geoffrey.mcgill
 
Posts: 3
Joined: Mon Nov 15, 2010 12:10 am

Re: DST related issue calculating Day numbers in MonthView

Postby geoffrey.mcgill » Mon Nov 15, 2010 9:25 am

I was thinking about this Brazil DST issue some more, and I'd be surprised if this doesn't cause a lot of problems within Brazil. For example...

The Brazil DST observance happens at 00:00:00, which at that exact moment, the time would then be rolled-back to 23:00:00 of the previous day. How/why have they convinced themselves that that make sense?

DST is typically observed at 02:00:00 because even if you lose an hour, at least you're still in the same day.
geoffrey.mcgill
 
Posts: 3
Joined: Mon Nov 15, 2010 12:10 am

Re: DST related issue calculating Day numbers in MonthView

Postby brian.moeskau » Mon Nov 22, 2010 11:25 am

Thanks for the detailed info Geoff. Haven't had a chance to dig into it yet, but I will soon and will let you know. Did not realize that anyone rolled back at 0:00:00. That's an interesting choice...
Personal Blog: Extraneous / Twitter: @bmoeskau / Meetup: Austin Bleeding Edge Web
User avatar
brian.moeskau
Site Admin
Site Admin
 
Posts: 1344
Joined: Sat Sep 18, 2010 5:00 pm
Location: Austin, Texas

Re: [OPEN-125] DST issue calculating Day numbers in MonthVie

Postby brian.moeskau » Thu Dec 02, 2010 1:13 pm

FYI, I am tracking this as a defect, but currently have it slated for 1.1 since DST will not be an issue again until next spring. Based on the potential complexity I'm not going to try and deal with it right this minute, but will definitely look into it later.
Personal Blog: Extraneous / Twitter: @bmoeskau / Meetup: Austin Bleeding Edge Web
User avatar
brian.moeskau
Site Admin
Site Admin
 
Posts: 1344
Joined: Sat Sep 18, 2010 5:00 pm
Location: Austin, Texas

Re: [OPEN-125] DST issue calculating Day numbers in MonthVie

Postby senacle » Thu Aug 01, 2013 1:15 am

Maybe my solution can help you : viewtopic.php?f=3&t=725&p=3081#p3081

My solution is for displaying the events inside the monthview calendar.
The bug related here is about displaying the monthview calendar alone.
senacle
 
Posts: 22
Joined: Wed Dec 14, 2011 4:01 am

Re: [OPEN-125] DST issue calculating Day numbers in MonthVie

Postby gabe.sidler » Sun Oct 13, 2013 4:21 am

Just a quick note: I can reproduce this issue in V 1.6.0 RC1.

Gabe
User avatar
gabe.sidler
Moderator
Moderator
 
Posts: 126
Joined: Sun Sep 25, 2011 4:34 am

Re: [OPEN-125] DST issue calculating Day numbers in MonthVie

Postby gabe.sidler » Tue Sep 23, 2014 10:52 am

Hi Brian
With October around the corner, daylight savings time (DST) will start soon in many countries and we at teamup.com are receiving an increasing number of support requests about the incorrect handling of DST switches. As I mentioned when we talked last time I spent some time recently to investigate this issue in more details and documented my findings below. Sorry for the long post, but I felt that this needed to be documented somewhere.

Who is affected?
I am aware of the following three time zones that are affected by incorrect handling of the DST start date:
  • America/Sao_Paulo
  • Australia/Sydney (Problem only with Safari browser)
  • Pacific/Auckland (Problem only with Safari browser)

What issues do users experience?
Users in the affected time zones experience the following problems with their calendar:
  • Monthly and weekly views show the day before the DST start date twice. For example, for the Sao Paulo time zone, Oct. 18, 2014 is shown twice. The days following the DST start date are all shifted by one day.
  • All events after the DST start date are not displayed. For example, for the Sao Paulo time zone, events after Oct. 19 are not displayed on monthly view and weekly view.
  • Selecting a range of days in monthly view and weekly view does not work correctly if the range includes the DST start date or is after the DST start date. Wrong days are selected and the shim used to highlight selected days is shown for the wrong days.
  • Using the arrow buttons in the calendar header to navigate backward and forward in time does not work correctly. For example, for Sao Paulo time zone and using the daily view, it is not possible to navigate from Oct 18 to Oct 19. The calendar gets stuck on Oct 18.
In short, the calendar becomes virtually unusable for any view that includes the DST start date.

What is the cause of these issues?
At first it might seem odd that three seemingly unrelated time zones show the same issues when starting DST. But, there is one common thing. In all three time zones mentioned above, the DST start takes place at midnight. In all other time zones known to me, the DST switch takes place at 2:00 am. Actually, I have to be more precise:
  • Sao Paulo time zone: The DST officially starts at midnight and as far as I know all systems implement the switch at midnight.
  • Sydney and Auckland time zone: The DST officially starts at 2:00 am in these two time zones. However, on Apple’s Safari browser the DST switch is wrongly implemented at midnight. This bug exists for years, has been reported to Apple multiple times (I submitted a bug report myself and was told that it is a duplicate) but for some reason does not get fixed. Other web browsers like Chrome and Firefox work fine on Apple devices. See also here: http://stackoverflow.com/questions/14839244/why-is-safari-confused-about-date-getday-for-dst-start-in-sydney-aus-time-zon

Research
I did some research on this issue and document here my findings:

First of all, it is important to understand how the DST start is implemented. I take Sao Paulo time zone as an example: At midnight between Oct. 18 and Oct. 19 2014, time is moved forward by one hour to Oct. 19, 2014, 01:00 am. In other words, the hour between 12:00am and 00:59:59 am on Oct. 19, 2014 is skipped and does not exist on that day. This is very nicely illustrated here: http://www.timeanddate.com/time/change/brazil/brasilia?year=2014

Secondly, it is important to understand how JavaScript implements this DST start. I did a few experiments with JSFiddle on a Windows computer configured to use the Sao Paulo (Brasilia) time zone. All test scripts are available here: http://jsfiddle.net/sv8bq8cj/23/

Script 1 below tests the conversion of date strings to Date objects.

Script 1:
Code: Select all
out(new Date('10/18/2014'));
out(new Date('10/18/2014 23:59:59'));
out(new Date('10/19/2014'));
out(new Date('10/19/2014 00:00:00'));
out(new Date('10/19/2014 00:00:01'));
out(new Date('10/19/2014 00:59:59'));
out(new Date('10/19/2014 01:00:00'));
out(new Date('10/19/2014 01:00:01'));
out(new Date('10/19/2014 02:00:00'));

Script 1 Output:
Code: Select all
Sat Oct 18 2014 00:00:00 GMT-0300 (Local Standard Time)
Sat Oct 18 2014 23:59:59 GMT-0300 (Local Standard Time)
Sat Oct 18 2014 23:00:00 GMT-0300 (Local Standard Time)
Sat Oct 18 2014 23:00:00 GMT-0300 (Local Standard Time)
Sat Oct 18 2014 23:00:01 GMT-0300 (Local Standard Time)
Sat Oct 18 2014 23:59:59 GMT-0300 (Local Standard Time)
Sun Oct 19 2014 01:00:00 GMT-0200 (Local Daylight Time)
Sun Oct 19 2014 01:00:01 GMT-0200 (Local Daylight Time)
Sun Oct 19 2014 02:00:00 GMT-0200 (Local Daylight Time)

Notice how JS does not accept any date between Oct. 19, 2014 12:00am and Oct. 19, 2014, 00:59:50am. If we try to create a date object in that hour, JS returns a date object set to one hour earlier. In particular, a date string of ‘10/19/2014’ is turned into a date object representing Oct 18, 2014, 23:00.

Script 2 explores how JS handles incrementing time across the DST start date.

Script 2:
Code: Select all
dt = new Date('10/18/2014 23:59:59');
t = dt.getTime();  // get time in milliseconds since 1970.
out(t);
out(new Date(t));
out(new Date(t + 1000)); // Add 1000 milliseconds
out(new Date(t + 2000)); // Add 2000 milliseconds

Script 2 Output:
Code: Select all
1413687599000
Sat Oct 18 2014 23:59:59 GMT-0300 (Local Standard Time)
Sun Oct 19 2014 01:00:00 GMT-0200 (Local Daylight Time)
Sun Oct 19 2014 01:00:01 GMT-0200 (Local Daylight Time)

Notice how adding one second to Oct 18, 2014 23:59:59 returns a date of Oct 19 2014 01:00:00. There is no way we can represent midnight on Oct 19, 2014.

Extensible Calendar uses the Ext.Date library in many places to increment dates. Script 3 explores how incrementing dates works across the DST start date of Oct 19, 2014:

Script 3:
Code: Select all
var dt = new Date('Oct 17 2014');
for (var i = 0; i < 5; i++) {
    out(dt);
    dt = Ext.Date.add(dt, Ext.Date.DAY, 1);
}

Script 3 Output:
Code: Select all
Fri Oct 17 2014 00:00:00 GMT-0300 (Local Standard Time)
Sat Oct 18 2014 00:00:00 GMT-0300 (Local Standard Time)
Sat Oct 18 2014 23:00:00 GMT-0300 (Local Standard Time)
Sun Oct 19 2014 23:00:00 GMT-0200 (Local Daylight Time)
Mon Oct 20 2014 23:00:00 GMT-0200 (Local Daylight Time)

Notice how Oct 18, 2014 appears twice in the output. The is because midnight does not exist for Oct 19, 2014.

A common date operation performed by the Extensible framework is to determine the end of a day for a given date object. The typical approach used to do that is this:

Script 4:
Code: Select all
var dt = new Date('10/17/2014');
out(dt);
dt = Ext.Date.add(dt, Ext.Date.DAY, 1);
dt = Ext.Date.clearTime(dt);
dt = Ext.Date.add(dt, Ext.Date.MILLI, -1);
out(dt);
var dt = new Date('10/18/2014');
out(dt);
dt = Ext.Date.add(dt, Ext.Date.DAY, 1);
dt = Ext.Date.clearTime(dt);
dt = Ext.Date.add(dt, Ext.Date.MILLI, -1);
out(dt);

Script 4 Output:
Code: Select all
Fri Oct 17 2014 00:00:00 GMT-0300 (Local Standard Time)
Fri Oct 17 2014 23:59:59 GMT-0300 (Local Standard Time)
Sat Oct 18 2014 00:00:00 GMT-0300 (Local Standard Time)
Fri Oct 17 2014 23:59:59 GMT-0300 (Local Standard Time)

Note how the approach succeeds to calculate the day end for 10/17/2014 but fails for 10/18/2014.

Proposal for Changes to the Extensible Library
Scripts 1 to 4 above demonstrate date operations that are frequently used by the Extensible Calendar framework but fail to properly handle the DST start for some time zones. In order to properly deal with time zones where DST starts at midnight, I propose the following changes to the Extensible framework.

1) AbstractCalendar::startDate
Property startDate of class AbstractCalendar holds the start date of a particular calendar view. It plays an important role in the functioning of the calendar views. In the past, property startDate was set to point to the beginning of a day, e.g. midnight. As we have seen in the tests above, midnight is not a valid time for days where the DST starts in some time zones. To avoid any DST issues, I propose to have startDate always point to midday (12:00pm).

2) Conversion of Date Strings to Date Objects
Extensible calendar frequently needs to convert date strings to date objects. As we have seen in script 1 above, this conversion fails to always return the expected result if the date string does not include a time specification. As a best practice I recommend to always add a time string to the date string to be converted if the date string does not include a time specification already.

Example: Instead of
Code: Select all
Ext.Date.parseDate('141019’, 'Ymd')

use
Code: Select all
Ext.Date.parseDate('141019' + ' 12:00', 'Ymd G:i')

to make this conversion DST save.

3) New functions Extensible.Date.getDayBeginning() and Extensible.Date.getDayEnd()
I propose to add two functions getDayBeginning() and getDayEnd() to class Extensible.Date. These two new function can be used to
  • Find the beginning of a day
  • Find the end of a day
  • Increment and decrement days
All these operations are performed in a way that properly handles the DST start for all time zones.

I have a version of the Extensible library with the proposed changes almost ready. Just need to do some more testing and cleanup and will then submit a PR. What do you think about the proposed changes?

Gabe
User avatar
gabe.sidler
Moderator
Moderator
 
Posts: 126
Joined: Sun Sep 25, 2011 4:34 am

Re: [OPEN-125] DST issue calculating Day numbers in MonthVie

Postby brian.moeskau » Tue Sep 23, 2014 11:58 pm

Hey Gabe, thanks for the very detailed info. Generally speaking your proposal sounds pretty good -- feel free to PR what you've got and I'll take a look. Thanks!
Personal Blog: Extraneous / Twitter: @bmoeskau / Meetup: Austin Bleeding Edge Web
User avatar
brian.moeskau
Site Admin
Site Admin
 
Posts: 1344
Joined: Sat Sep 18, 2010 5:00 pm
Location: Austin, Texas

Re: [OPEN-125] DST issue calculating Day numbers in MonthVie

Postby gabe.sidler » Wed Oct 29, 2014 1:18 pm

I am just documenting here another daylight savings time issue that I became aware of today. This time it affects the Pacific Time zone (US West coast).

Pacific time zone switches to winter time on November 2, 2014 at 3am. If I set my computer's time zone to Pacific Time zone and I try to create a new hourly event on Nov. 2, 2014, the new event will be displayed by one hour off.

Steps to reproduce:
  • Set your computers time zone to Pacific time.
  • Open demo calendar at http://ext.ensible.com/deploy/dev/examp ... t-app.html
  • Navigate to November 2, 2014
  • Enter a new event lasting from 8am to 10am.
  • The new event will be display incorrectly from 7am to 9am instead of 8am to 10am.

I can reproduce this error with current versions of Chrome and Firefox on Windows. Haven't tested other platforms and browsers. I will investigate if this is caused by similar issues as in the cases documented earlier in this thread.
User avatar
gabe.sidler
Moderator
Moderator
 
Posts: 126
Joined: Sun Sep 25, 2011 4:34 am

Next

Return to Bugs

Who is online

Users browsing this forum: No registered users and 1 guest

cron