caktus / django-timepiece

A multi-user Django application for tracking people's time on projects.
MIT License
361 stars 115 forks source link

Timezone inconsistency #503

Open ghost opened 11 years ago

ghost commented 11 years ago

We aren't doing a good job of handling timezones. I think that things work reliably when settings.USE_TZ is False. I would like to make timezone handling explicit & document our choices so that users know what to expect.

This approach seems pretty straightforward:

  1. Store everything in the database as UTC.
  2. Manipulate everything on the backend in UTC.
  3. When passing data to/from the front end, translate from settings.TIME_ZONE to UTC. Where practical, make it clear on the front end what the time zone is.

The bottom line: Things work for our use case, by coincidence if not design. No immediate changes are needed but this is probably the most important clean up we can make.

dpoirier commented 11 years ago

If we're dropping Django 1.3 support anytime soon, it'd make sense to wait. 1.4 had real timezone support, 1.3 didn't.

calebsmith commented 11 years ago

We also might be able to remove the pytz dependency after 1.3 support is dropped since we should be able to rely on the available Django machinery for everything involved.

ghost commented 11 years ago

I have dropped the hard requirement for pytz in the develop branch. Since Django strongly suggests using pytz with timezones, we would do well to add a similar note to the readme when we finally support timezones.

ghost commented 11 years ago

Scratch that. Seems that more work will be required to pull pytz out safely.

conrado commented 10 years ago

Hi, I'd like to run timepiece on mysql. Can you try to list the postgres dependencies or other considerations, so I can take try to make it db agnostic? I could even go as far as adding TZ to user settings, templates (where appropriate), and possibly a model or two (eg. Location)

wraybowling commented 10 years ago

@conrado, there have been discussions between @calebsmith and i lately about using [input type="time"] to take care of the front-end handling of time since it is easy to read/write/validate/interface with time values directly in the unix time format.

I agree with @rebecca-caktus's sentiment from over a year ago. As soon as unix time is used for everything on the back end, this sort of problem will disappear.

calebsmith commented 10 years ago

The biggest issue I'm aware of with regard to database agnosticism is our use of postgres' DATE TRUNC, specifically here: https://github.com/caktus/django-timepiece/blob/develop/timepiece/entries/models.py#L61-L66 . We've discussed having some sort of alternate code path here before for sqlite for faster testing, but the added complexity has always been somewhat of a nonstarter. Combining postgres' DATE TRUNC with python's itertools.group_by has proven very efficient and easy to reason about.

Last I checked, mysql didn't have support for this feature, or at least the details were quite different. It might be possible, but it also might be a bit of a rabbit hole. I don't want to discourage contribution, but I don't think that a feature for mysql support will be merged in if it seems to add much complexity or cause potential breakage. Perhaps mysql does have something like DATE TRUNC that would make this nearly trivial after all. Investigation in this vain is certainly welcome.

For this ticket, I think the most essential thing would be creating a migration path for existing data to make the transition of datetime naive to datetime aware and in UTC. After that, we have to fix all of the back-end code that this is likely to affect. I'd like to improve the time input front-end, and make the timezone part of that input, but I feel like that is a separate issue, at least beyond the point of a timezone choice that works in a very basic way.

With regard to the settings, we'd need the server's settings to have a timezone configured to act as the timezone for entries, invoices and so on. As far as input, I think the user profile could have a "default timezone" or similar setting to make the clock in/out procedure a bit easier. That said, it might also be nice to just default to the current timezone that JavaScript thinks is correct.