Issue660872
This issue tracker has been migrated to GitHub,
and is currently read-only.
For more information,
see the GitHub FAQs in the Python's Developer Guide.
Created on 2003-01-02 00:06 by pje, last changed 2022-04-10 16:06 by admin. This issue is now closed.
Messages (6) | |||
---|---|---|---|
msg13785 - (view) | Author: PJ Eby (pje) * | Date: 2003-01-02 00:06 | |
datetimetz.fromtimestamp(timestamp,tzinfo) creates a datetime which has the localtime() value of timestamp, with the tzinfo attached as its timezone. But this produces a counterintuitive result. Instead of getting the UTC time represented by timestamp, converted to the tzinfo timezone, one only ends up with a correct value if tzinfo is a perfect match for whatever 'localtime' is. This seems useless as well as counterintuitive, since one must therefore do this: datetimetz.fromtimestamp(stamp,localtime_tz).astimezone(tzinfo) to get what's desired. Or, one can do: datetimetz.utcfromtimestamp(stamp).replace(tzinfo=utc).astimezone(tzinfo) Both of these seem unreasonably complex ways of doing something simple: render this UTC timestamp as a datetime in a specified timezone. Similarly, I would expect datetimetz.now(tzinfo) to return the current time in the zone specified by tzinfo, but again this is not what it does. Similarly, you must do: datetimetz.now(localtime_tz).astimezone(tzinfo) or: datetimetz.utcnow().replace(tzinfo=utc).astimezone(tzinfo) to get the current time in the zone specified by tzinfo. Given that these constructors *know* what the UTC time is, why don't they behave more meaningfully? It seems to me that finding the current time in a timezone, or rendering a timestamp as it would be seen in a timezone, are common enough use cases, but I cannot think of any use cases for what the constructors actually do instead. |
|||
msg13786 - (view) | Author: Tim Peters (tim.peters) * | Date: 2003-01-02 01:14 | |
Logged In: YES user_id=31435 I always figured the use case for fromtimestamp(stamp, tz) was indeed so the user had a dead-easy way to attach their own local time tzinfo class to a timestamp, and that's all. I would find the behavior you describe counterintuitive instead: if I want a conversion, I'd rather ask for one explicitly (via astimezone()). |
|||
msg13787 - (view) | Author: PJ Eby (pje) * | Date: 2003-01-02 03:40 | |
Logged In: YES user_id=56214 But in your use case, if the timezone they attach is in fact equivalent to localtime, then the conversion would be a no-op anyway, right? So how would a conversion in the general case be wrong? At the very least, this is a documentation bug. If these constructors only produce meaningful results for a tzinfo that's exactly equivalent to the system's localtime(), then the docs should say so. Otherwise, someone can write code that appears to work, for example, on their own machine, and then fails when run on a machine with a different concept of localtime(). Now, if you can actually come up with a sensible use case for *wrongly* translating a UTC-based timestamp to a particular timezone, with the degree of wrongness depending on the difference between localtime() and the specified timezone, that might justify the constructor behavior. :) As it is, I find it hard to believe that whatever you come up with will be a more common need than rendering a UTC timestamp as a datetime value in a specified timezone. |
|||
msg13788 - (view) | Author: Tim Peters (tim.peters) * | Date: 2003-01-02 04:47 | |
Logged In: YES user_id=31435 I think Guido has more energy for this than I have (I'm pretty much burned out on this module), so assigned it to him. At the time fromtimestamp() was added, there wasn't any reasonable way to simply attach a tzinfo object to a datetimetz. About the best you could do is new = datetimetz(old.year, old.month, old.day, old.hour, old.minute, old.second, old.microsecond, tzinfo) So the use case of *simply* getting a local datetimetz out of a timestamp was quite a pain. datetimetz.fromtimestamp grew an optional tzinfo arg to ease that pain. There was no notion of timezone conversion at that time either, so of course none of the methods were intended to do any sort of conversion. Note that the primary constructor-- datetimetz --also takes all of its arguments as being in local time. It would strike me as inconsistent if fromtimestamp() didn't also take its argument as being in local time. Things changed since then, and I at least agree the docs should be clarified. But rather than make the constructors even more complicated, I'd rather drop the optional tzinfo arguments from fromtimestamp() and now(). There are at least two easy ways to attach a tzinfo tz to a datetimetz now: new = old.astimezone(tz) # no conversion if old was naive new = old.replace(tzinfo=tz) # no conversion ever and there's also an explict time zone conversion method. |
|||
msg13789 - (view) | Author: Guido van Rossum (gvanrossum) * | Date: 2003-01-02 16:46 | |
Logged In: YES user_id=6380 I think that Phillip's proposal is reasonable: when you give a tzinfo argument to datetimetz.fromtimestamp(), it should *convert* to the given tzinfo. I think the proper semantics are specified by this expression: datetimetz.utcfromtimestamp(stamp).replace(tzinfo=utc).astimezone(tzinfo) The rule for now() follows from this. BTW, I think it was a mistake to let astimezone() convert from/to naive times. It should only be used for conversion between tz-aware times; conversion from/to naive time should be done using dt.replace(tzinfo=...). |
|||
msg13790 - (view) | Author: Tim Peters (tim.peters) * | Date: 2003-01-23 21:50 | |
Logged In: YES user_id=31435 now() and fromtimestamp() now do "the right thing" with their optional tzinfo argument. The argument name was changed to "tz", BTW, as "tzinfo" had enough meanings already. Appropriate changes were checked into the Python datetimemodule.c and Zope3 _datetime.py implementations, + their test suites and LaTeX docs. Guido, your complaint about astimezone() was incidentally fixed in checkins prior to this -- astimezone() no longer supports converting between naive and aware datetimes, and also complains if the tzinfo object's utcoffset() or dst() methods return None. |
History | |||
---|---|---|---|
Date | User | Action | Args |
2022-04-10 16:06:05 | admin | set | github: 37681 |
2003-01-02 00:06:49 | pje | create |