
Introducing Times (for Python) - nvie81
http://nvie.com/posts/introducing-times/
======
jessedhillon
IMO dateutil provides this in a more transparent way by providing tzinfo
subclasses:

    
    
        py> from dateutil.tz import gettz
        py> from datetime import datetime
    
        py> new_york = gettz('America/New York')
        py> los_angeles = gettz('America/Los Angeles')
        py> minsk = gettz('Europe/Minsk')
    
        py> fmt = "%Y-%m-%d %H:%M%z"
        py> datetime.now(new_york).strftime(fmt)
          '2012-02-03 01:51-0500'
        py> datetime.now(los_angeles).strftime(fmt)
          '2012-02-02 22:51-0800'
        py> datetime.now(los_angeles).astimezone(minsk).strftime(fmt)
          '2012-02-03 09:51+0300'
    

For me, the most annoying thing about Python is that out of the box, AFAICT,
you cannot get a TZ-aware datetime. In fact, while tzinfo is part of the
standard library, I don't know of any included solution for making TZ-aware
datetime, short of writing your own subclasses for each timezone.

EDIT: datetime.utcnow() is TZ-aware, I meant any other timezone.

~~~
masklinn
> For me, the most annoying thing about Python is that out of the box, AFAICT,
> you cannot get a TZ-aware datetime.

That's because the stdlib would have to get updated every 3-6 months, which it
is not. Hence delegating to e.g. pytz for timezones provision.

> I don't know of any included solution for making TZ-aware datetime, short of
> writing your own subclasses for each timezone.

There isn't indeed, because there can't be an stdlib-provided way to do this
which is actually correct.

~~~
thristian
dateutil includes tzinfo implementations 'tzutc' (whose offset is always
zero), 'tzoffset' (whose offset is passed as a parameter) and 'tzlocal' (whose
offset is the value of time.timezone). All these could easily and safely be
implemented in the stdlib without having to push out updates every time the
Olson timezone database has a new release.

It also contains tzinfo implementations that read timezone definitions from a
system-wide copy of the Olson database (for most POSIX OSs) or the registry
(for Windows-based OSs). These could also be added to the standard library
without requiring regular Python updates, because the OS's usual timezone
update system will take care of things.

Perhaps the stdlib can't possibly solve timezone issues in all possible cases,
but it could be a lot more useful than it currently is.

------
latchkey
This is good, but for my app, we just decided to do all of the presentation on
the client side using javascript. This prevents us from having to know or
store the users tz at all. That way, whatever tz they are in is the correct
one. =)

We thought this might be an issue for things like emailing purchase receipts
to people since that is something that can't just be 'rendered' on the client,
but we ended up just asking ourselves "What would amazon do?" and looked at an
emailed Amazon receipt.

You will notice that there isn't a single time in the receipt other than when
the email was sent. Looked at a receipt from Apple. Same thing. Problem solved
by just removing the timestamp from the receipt.

Thought that was an interesting tidbit that I hadn't thought of before.

This is the JS library I used and am pretty happy with: <http://momentjs.com/>

~~~
mvanveen
Interesting.

I recently was evaluating JS and Python for handling time in my app. The goal
was not to localize to a specific timezone for the client, but rather to
inform the client of where in the world a current time is.

I ended up picking the Python backend solution because it was easier to reason
about with the more abstract `datetime` primitives.

------
tantalor
I don't think its fair to say one should "never work with local times". I
frequently work with "floating time", the opposite of "fixed time".

You can accept user input as (year, month, day, hour, minute, second), convert
to a common timezone, and store as seconds since epoch. To display, convert
back to the common timezone, but omit the timezone identifier. This is useful
for events which are local for the user, since they don't care about their own
timezone.

See the iCalendar spec,

 _They are used to represent the same hour, minute, and second value
regardless of which time zone is currently being observed. For example, an
event can be defined that indicates that an individual will be busy from 11:00
AM to 1:00 PM every day, no matter which time zone the person is in. In these
cases, a local time can be specified._

<http://www.kanzaki.com/docs/ical/dateTime.html>

------
tantalor
I don't think "2012-02-03 09:30:00+0100" is valid ISO 8601 because of the
space; it should be a "T" to be a proper "combined date and time"
representation.

 _The date and time representations may appear in proximity to each other,
often separated by a space or sometimes by other characters. In these cases
they occupy two separate fields in a data system, rather than a single
combined representation. This is usually done for human readability. Unlike
the previous examples, "2007-04-05 14:30" is considered two separate, but
acceptable, representations—one for date and the other for time. It is then
left to the reader to interpret the two separate representations as meaning a
single time point based on the context._

<http://en.wikipedia.org/wiki/ISO_8601>

That said, I prefer the "separated date and time" representation myself.

------
jkbr
This looks handy.

Btw, Django 1.4 (now alpha) is getting timezone support [1] and its
django.utils.timezones [2] features similar functionaliy.

[1]
[https://docs.djangoproject.com/en/dev/topics/i18n/timezones/...](https://docs.djangoproject.com/en/dev/topics/i18n/timezones/#time-
zones)

[2]
[https://github.com/django/django/blob/master/django/utils/ti...](https://github.com/django/django/blob/master/django/utils/timezone.py)

------
phzbOx
Great initiative. Dealing with timezone is a pain and I totally agree with you
that storing universal time is the way to go. It's a little bit like the
'validating input problem': Strongly validating and converting input/output so
that the entire application can be safe. I.e. it's not to the _sqrt_ function
to validate its parameters. (Although it'd throw an exception if it fails.)

------
jvdh
This solves one of my problems with datetime and timezones in Python. The
other being that it is totally awkward and bafflingly hard to add and
substract from datetime objects.

~~~
csytan
Why do you find it difficult?

    
    
        >>> datetime.datetime.now() - datetime.timedelta(days=1)
        datetime.datetime(2012, 2, 1, 23, 33, 30, 591993)

~~~
njharman
Doesn't do months or years. Who knows how it handles dst transitions.

I can't remember for sure but I don't think you can subtract two dates and get
a delta?

~~~
csytan
Months and years are tricky because they can consist of a variable number of
days. To me, it's a better way of handling things without being ambiguous. For
example, is one month from now exactly 30 days from today, or is it the next
month on the same month day? It's pretty simple to do either with the datetime
library.

When taking into account DST, you should first convert from local time to UTC
(pytz does this) before doing your calculations, then convert it back to local
time if needed.

And yes, you do get a delta when subtracting two dates.

~~~
masklinn
> Months and years are tricky because they can consist of a variable number of
> days.

Then again, days can consist of a variable number of seconds due to e.g. the
leap second.

