Opened 8 years ago
Closed 8 years ago
#27082 closed New feature (duplicate)
Make timezone.localtime() default to timezone.now() when no value is given
Reported by: | Baptiste Mispelon | Owned by: | nobody |
---|---|---|---|
Component: | Utilities | Version: | 1.10 |
Severity: | Normal | Keywords: | |
Cc: | Triage Stage: | Unreviewed | |
Has patch: | no | Needs documentation: | no |
Needs tests: | no | Patch needs improvement: | no |
Easy pickings: | no | UI/UX: | no |
Description
Sometimes I find that I need to get the current date in the context of the active time zone.
As far as I understand, the correct way to do this is timezone.localtime(timezone.now()).date()
.
It'd be nice if we localtime
would default to using timezone.now()
is no value is given, so that I could simply do timezone.localtime().date()
.
This should be straightforward to implement, except for the case where settings.USE_TZ = False
because timezone.now()
would then return a naive datetime and localtime()
would throw an error.
Change History (8)
comment:1 by , 8 years ago
comment:2 by , 8 years ago
Doesn't datetime.date.today()
use the system's timezone and not the active one?
follow-up: 7 comment:3 by , 8 years ago
I don't think this is about naive vs aware, but about accuracy. If a server's time zone is different than settings.TIME_ZONE
, then it is important to be able to answer the question "what is today in the the timezone of settings.TIME_ZONE
?" accurately. Near midnight different time zones will have different values for "today". This becomes useful when comparing other stored dates against "today", displaying "today", or storing "today" in the database. I have the following two convenience functions in my application to help make this job easier. For my application, they are always preferred over datetime.date.today()
, etc. They are heavily used.
def local_date(): return timezone.localtime(timezone.now()).date() def local_time(): return timezone.localtime(timezone.now()).time()
So I personally also see some value to this suggestion.
comment:4 by , 8 years ago
Ah you're right.
datetime.date.today()
uses the default time zone, not the current time zone. (I'm saying "default time zone" to mean "the time zone defined by settings.TIME_ZONE", which may be different from the system time zone.) That's because Django calls time.tzset(settings.TIME_ZONE)
on start up, but doesn't call time.tzset
when changing the active time zone.
So, yeah, timezone.localtime(timezone.now()).date()
is the best you can do at this point.
I think there's a ticket or a PR discussing timezone.localdate(aware_datetime) -> date
somewhere. timezone.localnow
has also been proposed in the past. I suppose we should add one or both.
comment:6 by , 8 years ago
Yes, that's the ticket I was referring to when I mentioned localdate
. (I have very spotty mobile connectivity this week, I can barely submit a comment and most pages don't load, so it's hard to research related discussions.)
comment:7 by , 8 years ago
Replying to jdufresne:
I don't think this is about naive vs aware, but about accuracy.
I would say that it's mostly a matter of providing a complete, but not redundant or overwhelming set of date/time/zones related APIs.
If a server's time zone is different than
settings.TIME_ZONE
, then it is important to be able to answer the question "what is today in the the timezone ofsettings.TIME_ZONE
?" accurately.
Actually the server's time zone doesn't matter for Django on Unix/Linux because Django sets the process' time zone to the value defined by TIME_ZONE
, and that's the default time zone for the application.
There are two cases where the server's time zone matters:
- on Windows, it must match
TIME_ZONE
because Windows doesn't support setting a process' time zone - if
TIME_ZONE = None
, Django uses the server time zone
Near midnight different time zones will have different values for "today".
Yes, I guess that's the reason why Baptiste filed this ticket.
I have the following two convenience functions in my application to help make this job easier. For my application, they are always preferred over
datetime.date.today()
, etc. They are heavily used.
def local_date(): return timezone.localtime(timezone.now()).date() def local_time(): return timezone.localtime(timezone.now()).time()
Since django.utils.timezone.localtime
is currently used to convert an aware datetime to a specific time zone, we have a bit of a naming problem here, but I'm +0 for adding the first of these two functions (under a name to be defined).
I'm not +1 because I believe that it's hard to get that kind of code right if you don't understand what you're doing, and writing these two one-liners is a good way to make sure the developer knows what's going on.
comment:8 by , 8 years ago
Resolution: | → duplicate |
---|---|
Status: | new → closed |
Thanks for your input Aymeric.
I think #25181 is a duplicate (I should really have searched before) so I'll close this one.
There's a lengthy discussion on the PR in the other ticket.
To get the current date in the context of the active timezone, just use
datetime.date.today()
. Dates are always naive, so there's no reason to provide an alternate constructor such asdjango.utils.timezone.now()
vsdatetime.datetime.(utc)now()
.localtime()
is intended to be a conversion function, thusvalue
is mandatory. It exists because thedatetime.astimezone
API isn't sufficient to implement conversions; pytz suggests a more complicated pattern whichlocaltime()
encapsulates.Please let me know if this addresses your needs or if you still think improvements are needed.