
Python Enhancement Proposal 495: Local Time Disambiguation - philipn
https://www.python.org/dev/peps/pep-0495/
======
kbenson
I'm not sure the rationale behind this. That is, the rationale section of the
proposal does a poor just of explaining any case where this is actually a
problem.

In every case where I've seen this problem, it's a matter of people either not
storing the timezone along with the local time, or not storing in UTC time. A
local time with a timezone is a unique time, it does not occur twice. A UTC
time additionally does not occur twice. Store a time zone along with the date
and time or store in UTC and convert on use.

Note: If there are instances where a second is repeated, it's rare special
occurrence that developing a formalized interface for seems like overkill.

~~~
deathanatos
> A local time with a timezone is a unique time, it does not occur twice.

If you define timezone as an IANA timezone, this is incorrect: a whole slew of
local times repeat during a DST fallback event: you'll have a (1:30 AM
(dst=True), America/New_York), and then a (1:30 AM (dst=False),
America/New_York); that "dst=True|False" bit is the only difference, and that
needs to get stored. If you consider "America/New_York" to be the TZ, then
storing that bit on the TZ isn't appropriate, as it depends on a particular
timestamp.

If you've ever worked with PyTZ, there's a sort of rule of "just call
normalize() always"; otherwise, you'll get funny answers to some
introspections on the datetime instance: things like the offset being not what
a local would say the offset should be. My understanding is that pytz stores
the dst flag on the timezone instance itself; things get funny because the
timezone instance is not given a chance to update after arithmetic on the
datetime instance.

(Really, I feel like the whole thing would work better if there was a separate
class for "instant in time" and a function for, "convert this instant in time
to Gregorian year/month/day/etc. in this TZ", which then returned a broken-
out-type. (And a reverse, of course, for building "Instant" instances.))

UTC datetime + IANA TZ (if relevant) is the way to go. Alas, not all data is
so nice.

~~~
kbenson
Really I was thinking of it as a distinct timezone that must be tracked.
Whether the DST and non-DST versions label themselves as such, the
representation used to track time must distinguish whether DST is active or
not to display the correct local time. Really, when I say store local time +
timezone, I mean local time plus identifier that gets you to the same unique
timezone representation in your medium (python, in this case).

Personally, I just _always_ convert to UTC and store that. It changes the
problem from one of data fidelity to display or computation annoyance, and
annoyances are easy to reduce or eliminate with tooling.

~~~
deathanatos
> Really I was thinking of it as a distinct timezone that must be tracked.
> Whether the DST and non-DST versions label themselves as such, the
> representation used to track time must distinguish whether DST is active or
> not to display the correct local time. Really, when I say store local time +
> timezone, I mean local time plus identifier that gets you to the same unique
> timezone representation in your medium (python, in this case).

I guess that's my point: the IANA identifier is a well-known way to serialize
a TZ, but doesn't include DST flags because they're not relevant. I think if
you wanted to store something like a Python tzinfo object, the easiest way is
just storing (local time, offset from UTC); (maybe (local time, offset from
UTC, IANA TZ ID), if you want to keep the TZ)

tzinfo's don't really have a defining quality in Python, I've found. You can
end up — depending on libraries used — with two tzinfos that both conceptually
are "UTC", but don't compare equal…

Now that I've thought about it again, I'm not entirely sure that the DST flag
+ TZ name by itself is sufficient, mostly in the case of a TZ deciding to
change their offset.

> just always convert to UTC and store that. It changes the problem from one
> of data fidelity to display

The right thing to do, and for the right reasons.

------
toyg
Terrible PEP, I hope it gets rejected. One-off flags like this are hacks that
shouldn't be in stdlib. It simply stinks, in an area (time handling) where the
stdlib does not really smell like roses already.

Dealing with time adjustments is the OS's job, not userland. If your job has
to be scheduled exactly and cannot rely on the OS, and you refuse to deal with
UTC, it's your own damn fault and you can always just use a long-running
process with timers.

~~~
bliti
I agree. It's library baggage.

------
lifeisstillgood
So :

Time in UK is currently UTC +1 (BST) At 2am on 25 OCT we will return to GMT /
UTC. It will therefore become 1am, and for the next hour all times will have
happened before

The idea is to put a bit flag that says "alreadyseenthistime"

It seems to me this is a solution to the wrong problem.

Store all strings as bytes, assuming UTF-8, store all times as longs assuming
UTC

If we convert all python datelines to non-naive (ie embedded with a TZ) then
we are forced always to choose an encoding just like in strings. The right
encoding is to always assume incoming dates are UTC, to throw error if they
are non naive, and to assume that local clocks are set correctly (which we do
anyway)

I need to read it more carefully - but it seems the wrong solution

------
Marazan
In general any solution to datetimes that doesn't involve the time being in
UTC is solving thew wrong problem.

~~~
akvadrako
I would disagree. UTC is ambiguous and unpredictable. Computers should really
be based on GPST (seconds since 1980-Jan-6 UTC).

~~~
ubernostrum
If you want to be pedantic about getting rid of unpredictability in your time
measurement, use TAI.

------
IanCal
When the clocks change, don't you shift timezone? There aren't duplicate times
in BST, we just switch from GMT to BST and then back.

> In these situations, the information displayed on a local clock (or stored
> in a Python datetime instance) is insufficient to identify a particular
> moment in time.

Does the datetime instance not store the timezone?

~~~
msm23
Yes, you could get the information from the timezone, but how would one do
that in code?

The only time that one has the time fold is when you turn the clock backward
(let's just call that shifting from daylight savings to standard timezone).
And this would only affect code which used wall clock time (time as it's read,
e.g. 1:30am PDT), and would also only affect code which wanted to run
something only once at a time within that fold (e.g. 1:30am ... not on both
1:30am's).

So, using the timezone method, just check to see if your current 1:30am is in
your daylight savings timezone. Hurray! You're in the clear. Go ahead and do
that thing you wanted to do only on the first 1:30am.

But the next day you're going to run into a problem. The only 1:30am you're
going to get is in the standard timezone. So now you have to check for this
timezone change only on the day of the change, which is yet another piece of
data you have to keep track of. On the day of the change, do this timezone
comparison, and on every other day don't worry about it.

When the clock hits your interesting time of 1:30am, just check to see if
today is the day of the change, check what the current timezone is, check what
the daylight savings time zone is, check to see if those those two values are
the same, and now do your thing. Otherwise, just do your thing.

All of the above also ignores that people change times at different times
(11pm, 1am, 2am, 3am), some don't change a full hour, and some don't change at
all.

The proposal gets rid of all of that convoluted logic in everyone's programs,
and instead it provides a single boolean value: is this the second time I've
seen this time because of daylight savings shenanigans.

~~~
IanCal
> The proposal gets rid of all of that convoluted logic in everyone's programs

Does it? It doesn't cover the scheduling problem the other half of the year
when the clocks move the other direction.

> So now you have to check for this timezone change only on the day of the
> change, which is yet another piece of data you have to keep track of.

If running a job twice is a problem, then why not check that the job has not
already been run?

> is this the second time I've seen this time

Is this unambiguous? If it's 2015-10-25-01-30-00 GMT, have I seen that time
before? In the UK, yes, in Mali no.

------
mayoff
The more I'm exposed to other date/time libraries, the more impressed I become
with Apple's date/time library.

[https://developer.apple.com/library/mac/documentation/Cocoa/...](https://developer.apple.com/library/mac/documentation/Cocoa/Conceptual/DatesAndTimes/DatesAndTimes.html#//apple_ref/doc/uid/10000039-SW1)

