Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]


Groups > comp.lang.python > #40881 > unrolled thread

Why are timezone aware and naive datetimes not distinct classes?

Started byRoy Smith <roy@panix.com>
First post2013-03-08 13:41 -0500
Last post2013-03-11 20:32 +0000
Articles 9 — 5 participants

Back to article view | Back to comp.lang.python


Contents

  Why are timezone aware and naive datetimes not distinct classes? Roy Smith <roy@panix.com> - 2013-03-08 13:41 -0500
    Re: Why are timezone aware and naive datetimes not distinct classes? Nobody <nobody@nowhere.com> - 2013-03-08 21:33 +0000
      Re: Why are timezone aware and naive datetimes not distinct classes? Chris Angelico <rosuav@gmail.com> - 2013-03-09 09:01 +1100
        Re: Why are timezone aware and naive datetimes not distinct classes? Nobody <nobody@nowhere.com> - 2013-03-09 19:14 +0000
          Re: Why are timezone aware and naive datetimes not distinct classes? Roy Smith <roy@panix.com> - 2013-03-09 14:40 -0500
            Re: Why are timezone aware and naive datetimes not distinct classes? Nobody <nobody@nowhere.com> - 2013-03-09 23:38 +0000
          Re: Why are timezone aware and naive datetimes not distinct classes? Chris Angelico <rosuav@gmail.com> - 2013-03-10 09:28 +1100
    Re: Why are timezone aware and naive datetimes not distinct classes? Adam Tauno Williams <awilliam@whitemice.org> - 2013-03-11 13:27 -0400
      Re: Why are timezone aware and naive datetimes not distinct classes? djc <djc@kangoo.invalid> - 2013-03-11 20:32 +0000

#40881 — Why are timezone aware and naive datetimes not distinct classes?

FromRoy Smith <roy@panix.com>
Date2013-03-08 13:41 -0500
SubjectWhy are timezone aware and naive datetimes not distinct classes?
Message-ID<roy-3BFD51.13412708032013@70-1-84-166.pools.spcsdns.net>
To make a long (and painful) story short, I've got a (large) list of 
datetimes, and was getting some bizarre errors working with it.  One of 
the things I tried while debugging the problem was verifying that all 
the elements of the list were indeed datetimes:

In [59]:  set(type(foo) for foo in x)
Out[59]:  set([datetime.datetime])

Well, it turns out, one of them was a timezone-aware datetime, and all 
the others were naive!  I finally figured it out when I tried

max(x)

and got

TypeError: can't compare offset-naive and offset-aware datetimes

So, the question is, WHY aren't aware and naive datetimes separate 
classes?  They share many attributes and methods, but not all.  It seems 
like they should both be subclasses of some common BaseDatetime.  Was 
not splitting them into two classes a deliberate design decision?

[toc] | [next] | [standalone]


#40903

FromNobody <nobody@nowhere.com>
Date2013-03-08 21:33 +0000
Message-ID<pan.2013.03.08.21.33.44.615000@nowhere.com>
In reply to#40881
On Fri, 08 Mar 2013 13:41:27 -0500, Roy Smith wrote:

> So, the question is, WHY aren't aware and naive datetimes separate 
> classes?  They share many attributes and methods, but not all.

They share all attributes and methods.

You could just as well ask why positive and negative floats aren't
separate classes (based upon the fact that e.g. math.sqrt() and math.log()
raise domain errors for negative floats).

Just because certain operations aren't defined for all values (or all
combinations of values), that doesn't make the values where those
operations aren't defined into a distinct type.

[toc] | [prev] | [next] | [standalone]


#40907

FromChris Angelico <rosuav@gmail.com>
Date2013-03-09 09:01 +1100
Message-ID<mailman.3104.1362780081.2939.python-list@python.org>
In reply to#40903
On Sat, Mar 9, 2013 at 8:33 AM, Nobody <nobody@nowhere.com> wrote:
> On Fri, 08 Mar 2013 13:41:27 -0500, Roy Smith wrote:
>
>> So, the question is, WHY aren't aware and naive datetimes separate
>> classes?  They share many attributes and methods, but not all.
>
> They share all attributes and methods.
>
> You could just as well ask why positive and negative floats aren't
> separate classes (based upon the fact that e.g. math.sqrt() and math.log()
> raise domain errors for negative floats).
>
> Just because certain operations aren't defined for all values (or all
> combinations of values), that doesn't make the values where those
> operations aren't defined into a distinct type.

They represent different things, though. A naive datetime is kinda
like an integer - an abstract thing that has meaning only as the
programmer gives it meaning; an aware datetime unambiguously
represents an instant in time. SQL has completely different data types
for "TIMESTAMP WITHOUT TIME ZONE" and "TIMESTAMP WITH TIME ZONE".

As I see it, a naive datetime simply does not have a timezone. The
fact that it may have an attribute that's set to None doesn't mean
that it "shares all attributes" with aware datetimes; if they were
implemented completely separately (without even a common base class),
the most obvious difference would be the complete absence of timezone
attribute on the naive type.

Conceptually, Roy's notion of a common base class makes good sense.
But I can't speak for the Python datetime module as I've hardly used
it; there may be practical considerations that mean the current model
works better. All I can say is, there's definitely more difference
between aware and naive datetimes than there is between positive and
negative floats.

ChrisA

[toc] | [prev] | [next] | [standalone]


#40967

FromNobody <nobody@nowhere.com>
Date2013-03-09 19:14 +0000
Message-ID<pan.2013.03.09.19.14.59.699000@nowhere.com>
In reply to#40907
On Sat, 09 Mar 2013 09:01:17 +1100, Chris Angelico wrote:

> As I see it, a naive datetime simply does not have a timezone.

The distinction between aware and naive isn't whether the .tzinfo member
is None, but whether self.utcoffset() returns None (which can occur either
if self.tzinfo is None or if self.tzinfo.utcoffset(self) returns None).

IOW, an "aware" time/datetime can be converted to a UTC time/datetime, a
"naive" one can't, although it can still have a timezone which isn't
referenced to UTC.

The distinction may actually matter for times in the far future, as you
can't reliably predict how or when timezone defintions will change.
Converting a future datetime to UTC based upon the current timezone rules
is at best an estimate. For this reason, "appointments" should always be
kept in local time, so that you don't get errors if the timezone rules
(or the timezone) change between the time an appointment is made and the
time it occurs.

[toc] | [prev] | [next] | [standalone]


#40970

FromRoy Smith <roy@panix.com>
Date2013-03-09 14:40 -0500
Message-ID<roy-496325.14401409032013@70-1-84-166.pools.spcsdns.net>
In reply to#40967
In article <pan.2013.03.09.19.14.59.699000@nowhere.com>,
 Nobody <nobody@nowhere.com> wrote:

> The distinction may actually matter for times in the far future, as you
> can't reliably predict how or when timezone defintions will change.

Sadly, this is true.

> For this reason, "appointments" should always be
> kept in local time, so that you don't get errors if the timezone rules
> (or the timezone) change between the time an appointment is made and the
> time it occurs.

Well, sort of.  Future scheduled activities (which I assume is what you 
mean by "appointments") should be kept in whatever timezone makes sense 
for that activity.  For example, I'm on NASA's mailing list to receive 
alerts when the ISS is going to be visible to the naked eye at my 
location.  The last one said:

> Time: Wed Feb 27 6:17 PM, Visible: 4 min, Max Height: 54 degrees, 
> Appears: W, Disappears: SE

If I wanted to put that on my calendar, I really should convert it to 
UTC and record it that way.  If the folks who mess with these things 
were to suddenly decide to move when DST starts, the space station isn't 
going to adjust its orbit to accommodate that.

Likewise, let's say I make an appointment to have a phone call with 
somebody in Caliornia (I'm in New York) at some future date.  I put on 
my calendar "Call with Joe, 5 PM".  Joe puts on his, "Call with Roy, 2 
PM".  The idiots in Albany and/or Sacramento decide to mess with the 
timezones and one state changes the rules.  We're going to miss our 
phone call.  Had we both recorded the arranged time in UTC, we'd get to 
talk to each other.

[toc] | [prev] | [next] | [standalone]


#40985

FromNobody <nobody@nowhere.com>
Date2013-03-09 23:38 +0000
Message-ID<pan.2013.03.09.23.38.42.444000@nowhere.com>
In reply to#40970
On Sat, 09 Mar 2013 14:40:14 -0500, Roy Smith wrote:

> Future scheduled activities (which I assume is what you 
> mean by "appointments") should be kept in whatever timezone makes sense 
> for that activity.  For example, I'm on NASA's mailing list to receive 
> alerts when the ISS is going to be visible to the naked eye at my 
> location.  The last one said:
> 
>> Time: Wed Feb 27 6:17 PM, Visible: 4 min, Max Height: 54 degrees, 
>> Appears: W, Disappears: SE
> 
> If I wanted to put that on my calendar, I really should convert it to 
> UTC and record it that way.

Indeed; that is an appropriate use of UTC.

> Likewise, let's say I make an appointment to have a phone call with 
> somebody in Caliornia (I'm in New York) at some future date.  I put on 
> my calendar "Call with Joe, 5 PM".  Joe puts on his, "Call with Roy, 2 
> PM".  The idiots in Albany and/or Sacramento decide to mess with the 
> timezones and one state changes the rules.  We're going to miss our 
> phone call.  Had we both recorded the arranged time in UTC, we'd get to 
> talk to each other.

Maybe. But if the time was chosen so as not to conflict with other
activites, changes to timezone(s) will often result in corresponding
changes to schedules, meaning that one or both parties will no longer be
available at the original UTC time (or even at any time, if both have busy
schedules).

Which is why "future scheduled activities" which require multiple people
to physically meet at a specific place and time are normally scheduled
in terms of "the /de jure/ timezone of that location, as applicable on
that date", rather than in UTC or even a named timezone.

Similarly, the policies of a corporation which operates in multiple
timezones within a single country may dictate times which are common (in
HH:MM terms) to all locations but which are interpreted according to each
location's /de jure/ timezone (e.g. fast food chains' "breakfast" menus).

[toc] | [prev] | [next] | [standalone]


#40982

FromChris Angelico <rosuav@gmail.com>
Date2013-03-10 09:28 +1100
Message-ID<mailman.3141.1362868115.2939.python-list@python.org>
In reply to#40967
On Sun, Mar 10, 2013 at 6:14 AM, Nobody <nobody@nowhere.com> wrote:
> On Sat, 09 Mar 2013 09:01:17 +1100, Chris Angelico wrote:
>
>> As I see it, a naive datetime simply does not have a timezone.
>
> The distinction between aware and naive isn't whether the .tzinfo member
> is None, but whether self.utcoffset() returns None (which can occur either
> if self.tzinfo is None or if self.tzinfo.utcoffset(self) returns None).
>
> IOW, an "aware" time/datetime can be converted to a UTC time/datetime, a
> "naive" one can't, although it can still have a timezone which isn't
> referenced to UTC.

I stand corrected. Though the distinction I made in my first paragraph
is still valid: an aware datetime represents an instant in time, a
naive one is a tagged piece of arbitrary data.

On Sun, Mar 10, 2013 at 6:40 AM, Roy Smith <roy@panix.com> wrote:
> Future scheduled activities (which I assume is what you
> mean by "appointments") should be kept in whatever timezone makes sense
> for that activity.

Agreed; and in some specific circumstances, it's even possible to
fight the whole mess of timezones. My online Dungeons and Dragons
group schedules everything on UTC - for example, the server quotes the
current time as Sat 22:26, and I have a session at Sun 02:00, so
anyone can figure out how long until session without worrying about
timezones or Daylight Robbery Time. Of course, that _does_ come at a
cost; mainly it's the USA-based players who get confused (which
surprises me somewhat, tbh).

ChrisA

[toc] | [prev] | [next] | [standalone]


#41081

FromAdam Tauno Williams <awilliam@whitemice.org>
Date2013-03-11 13:27 -0400
Message-ID<mailman.3199.1363024033.2939.python-list@python.org>
In reply to#40881
On Fri, 2013-03-08 at 13:41 -0500, Roy Smith wrote:
> To make a long (and painful) story short, I've got a (large) list of 
> datetimes, and was getting some bizarre errors working with it.  One of 
> the things I tried while debugging the problem was verifying that all 
> the elements of the list were indeed datetimes:
> In [59]:  set(type(foo) for foo in x)
> Out[59]:  set([datetime.datetime]

Because date/time management in Python is *@*&@R&*(R *@&Y terrible!
Period, full-stop, awful, crappy, lousy, and aggravating.  The design is
haphazard and error inducing.

Pass through the list once and convert them all the UTC [or I suppose,
make them all naive].

BTW, this page is a life and sanity saver:

<http://taaviburns.ca/what_you_need_to_know_about_datetimes/datetime_transforms.html>

And one of my own tricks is posted here:

<http://www.whitemiceconsulting.com/2012/10/setting-course-for-utc.html>

> Well, it turns out, one of them was a timezone-aware datetime, and all 
> the others were naive!  I finally figured it out when I tried

Welcome!

-- 
Adam Tauno Williams  GPG D95ED383
Systems Administrator, Python Developer, LPI / NCLA

[toc] | [prev] | [next] | [standalone]


#41090

Fromdjc <djc@kangoo.invalid>
Date2013-03-11 20:32 +0000
Message-ID<khlf0k$b0q$1@news.albasani.net>
In reply to#41081
On 11/03/13 17:27, Adam Tauno Williams wrote:

> Because date/time management in Python is *@*&@R&*(R *@&Y terrible!
> Period, full-stop, awful, crappy, lousy, and aggravating.  The design is
> haphazard and error inducing.

+1


-- 
djc

[toc] | [prev] | [standalone]


Back to top | Article view | comp.lang.python


csiph-web