keithamus / tempus

Tempus - Time for a new Date()
http://tempus-js.com
Other
94 stars 9 forks source link

Add better support for timezones #2

Closed keithamus closed 12 years ago

keithamus commented 12 years ago

Timezone support does not work very well, as it spills over hours, days, etc.

For example, if you are at the end of the day (say, the 23rd hour) in UTC, and you set the timezone to +0400, then getHours() will return 26. Similarly getDate() will return the wrong date (as the timezone is now the next day).

This bubbles up to Days, Weeks, Months, Years. Each one can hit an edge where the timezone should rollover the unit (e.g days) but doesn't.

Proposed Solutions:

  1. Add a method which is called inside each of the unit getters to check for spill-over, and adjust accordingly.
  2. Maintain 2 private Date() objects, one is the UTC representation of date, the other is the timezone representation of the date. Use UTC* methods for all internal Date() calls.
  3. Set the internal _date object only using UTC methods (ignoring _date's internal tz data) and including Tempus tz data, and for Tempus' UTC methods 0 out the timezone, get the date info and put the tz back.

My money is on style 3

llafuente commented 12 years ago

Hi,

There is another issues related that is bothering me lately.

Summer time. Spain is GMT+1, but in summer is like GMT+2

So now I have some dates with the 25 hours, and the countdowns ends because the day is not updated properly...

I prefer the second method. So i will try it

keithamus commented 12 years ago

Having explored each of these in depth, here are the disadvantages for each (respectively). I still think style 3 is the one to go for but it comes a pretty big price.

  1. This way of doing it is pretty crap, a private is called on pretty much all methods, adding size to the codebase, and the method itself has to be pretty comprehensive, doing lots of ops to correct timezone misshaps (needs to check for rollover minutes, hours, days, months, years). This is also probably the worst for performance.
  2. Extra ops for each type of date leads to a lot of code. It essentially doubles the codebase, which is pretty depressing. It also creates code where it is difficult to assert which date to use.
  3. So far what I've done with this has the least impact to code size and performance, and it seems more reliable, but it has a massive side-effect: the dates do not automatically adjust to DST. While dates with manual tzs shouldn't, if you're setting tz to locale then it should track DST changes. So maybe use this method, plus a load of code to check if we're using locale timezone, and if so track DST tz changes?