Time
Recently I built a scheduling application for my work web site. It’s pretty awesome.
Anywho, I had to learn about time, and how it’s handled. Going into this, I always thought that if I were a systems administrator all over again I would have my machines all run in GMT to eliminate timezone problems. Now that I’ve learned, I know it’s now called “UTC” and it’s still a really really really really really good idea to do as much as you can in UTC and only present localized times only when the user sees them.
I learned about how time works in four tools: Postgres, Python, Django, and Javascript.
Postgres
Totally sweet support for time. You can say
generate_series(date(X at time zone 'UTC' - interval '120 minutes'), date(Y at time zone 'UTC - interval '120 minutes'), '1 day'::interval)
and get all the dates between X and Y. Everything about datetimes is super duper good.
Python
datetime library is pretty good. It is a little unfortunate (although understandable) that you need a non-Python library (usually pytz) to localize times. (This is because Python does not want to handle the political problems (literally) of keeping timezone definitions up to date.)
Notably, I built a small library called “time_shortcuts” to help with common time stuff:
- utc_dt(str)–convert the string into a UTC-localized datetime object.
- utc_now()–right now in UTC
- xtimerange(start, end, step)–walk from start to end by step.
- minute_diff(start, end)–returns a diff between start and end in minutes, not days. makes a bad assumption about how many minutes are in a day.
This way I could write utc_dt(“2013-04-25 18:00:00”) and know I was getting back a datetime timezone-aware object. This is much more helpful than it should be.
Django
Django gets a little angry if you feed it DateTimeFields that aren’t timezone-aware. Hence the above helper library. Other than that, it makes the Python <-> Postgres interface transparent, which is all you can ask for. You deal in Datetime objects, and it handles Postgres.
I have one notable instance where I call straight SQL (using a cursor) so that I can do some of the Postgres goodness described above.
Javascript
Good stuff: Javascript’s Date() object.
Bad stuff: Javascript’s Date() object.
It is nice to call
new Date().getTimezoneOffset()
and get the timezone diff in minutes. It is also nice to be able to call .getUTCHours().
It is unfortunate that I don’t know of a way to change the timezone that Javascript uses for a given session. This resulted in me creating a clunky <select id=”timezone”> object that has all the timezones and their minute offset and this becomes a weird interactive variable that redraws the time-related parts of the page when it’s changed.