[Django] #27082: Make timezone.localtime() default to timezone.now() when no value is given

7 views
Skip to first unread message

Django

unread,
Aug 18, 2016, 4:15:35 AM8/18/16
to django-...@googlegroups.com
#27082: Make timezone.localtime() default to timezone.now() when no value is given
---------------------------------------+------------------------
Reporter: bmispelon | Owner: nobody
Type: New feature | Status: new
Component: Utilities | Version: 1.10
Severity: Normal | Keywords:
Triage Stage: Unreviewed | Has patch: 0
Needs documentation: 0 | Needs tests: 0
Patch needs improvement: 0 | Easy pickings: 0
UI/UX: 0 |
---------------------------------------+------------------------
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.

--
Ticket URL: <https://code.djangoproject.com/ticket/27082>
Django <https://code.djangoproject.com/>
The Web framework for perfectionists with deadlines.

Django

unread,
Aug 18, 2016, 8:49:05 AM8/18/16
to django-...@googlegroups.com
#27082: Make timezone.localtime() default to timezone.now() when no value is given
-----------------------------+--------------------------------------

Reporter: bmispelon | Owner: nobody
Type: New feature | Status: new
Component: Utilities | Version: 1.10
Severity: Normal | Resolution:

Keywords: | Triage Stage: Unreviewed
Has patch: 0 | Needs documentation: 0
Needs tests: 0 | Patch needs improvement: 0
Easy pickings: 0 | UI/UX: 0
-----------------------------+--------------------------------------

Comment (by aaugustin):

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 as `django.utils.timezone.now()` vs
`datetime.datetime.(utc)now()`.

`localtime()` is intended to be a conversion function, thus `value` is
mandatory. It exists because the `datetime.astimezone` API isn't
sufficient to implement conversions; pytz suggests a more complicated
pattern which `localtime()` encapsulates.

Please let me know if this addresses your needs or if you still think
improvements are needed.

--
Ticket URL: <https://code.djangoproject.com/ticket/27082#comment:1>

Django

unread,
Aug 18, 2016, 8:54:16 AM8/18/16
to django-...@googlegroups.com
#27082: Make timezone.localtime() default to timezone.now() when no value is given
-----------------------------+--------------------------------------

Reporter: bmispelon | Owner: nobody
Type: New feature | Status: new
Component: Utilities | Version: 1.10
Severity: Normal | Resolution:

Keywords: | Triage Stage: Unreviewed
Has patch: 0 | Needs documentation: 0
Needs tests: 0 | Patch needs improvement: 0
Easy pickings: 0 | UI/UX: 0
-----------------------------+--------------------------------------

Comment (by bmispelon):

Doesn't `datetime.date.today()` use the system's timezone and not the
active one?

--
Ticket URL: <https://code.djangoproject.com/ticket/27082#comment:2>

Django

unread,
Aug 18, 2016, 9:36:04 AM8/18/16
to django-...@googlegroups.com
#27082: Make timezone.localtime() default to timezone.now() when no value is given
-----------------------------+--------------------------------------

Reporter: bmispelon | Owner: nobody
Type: New feature | Status: new
Component: Utilities | Version: 1.10
Severity: Normal | Resolution:

Keywords: | Triage Stage: Unreviewed
Has patch: 0 | Needs documentation: 0
Needs tests: 0 | Patch needs improvement: 0
Easy pickings: 0 | UI/UX: 0
-----------------------------+--------------------------------------

Comment (by jdufresne):

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.

--
Ticket URL: <https://code.djangoproject.com/ticket/27082#comment:3>

Django

unread,
Aug 18, 2016, 9:38:45 AM8/18/16
to django-...@googlegroups.com
#27082: Make timezone.localtime() default to timezone.now() when no value is given
-----------------------------+--------------------------------------

Reporter: bmispelon | Owner: nobody
Type: New feature | Status: new
Component: Utilities | Version: 1.10
Severity: Normal | Resolution:

Keywords: | Triage Stage: Unreviewed
Has patch: 0 | Needs documentation: 0
Needs tests: 0 | Patch needs improvement: 0
Easy pickings: 0 | UI/UX: 0
-----------------------------+--------------------------------------

Comment (by aaugustin):

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.

--
Ticket URL: <https://code.djangoproject.com/ticket/27082#comment:4>

Django

unread,
Aug 18, 2016, 9:43:52 AM8/18/16
to django-...@googlegroups.com
#27082: Make timezone.localtime() default to timezone.now() when no value is given
-----------------------------+--------------------------------------

Reporter: bmispelon | Owner: nobody
Type: New feature | Status: new
Component: Utilities | Version: 1.10
Severity: Normal | Resolution:

Keywords: | Triage Stage: Unreviewed
Has patch: 0 | Needs documentation: 0
Needs tests: 0 | Patch needs improvement: 0
Easy pickings: 0 | UI/UX: 0
-----------------------------+--------------------------------------

Comment (by bmispelon):

Are you talking about #25181 ?

--
Ticket URL: <https://code.djangoproject.com/ticket/27082#comment:5>

Django

unread,
Aug 18, 2016, 9:56:07 AM8/18/16
to django-...@googlegroups.com
#27082: Make timezone.localtime() default to timezone.now() when no value is given
-----------------------------+--------------------------------------

Reporter: bmispelon | Owner: nobody
Type: New feature | Status: new
Component: Utilities | Version: 1.10
Severity: Normal | Resolution:

Keywords: | Triage Stage: Unreviewed
Has patch: 0 | Needs documentation: 0
Needs tests: 0 | Patch needs improvement: 0
Easy pickings: 0 | UI/UX: 0
-----------------------------+--------------------------------------

Comment (by aaugustin):

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.)

--
Ticket URL: <https://code.djangoproject.com/ticket/27082#comment:6>

Django

unread,
Aug 18, 2016, 10:04:19 AM8/18/16
to django-...@googlegroups.com
#27082: Make timezone.localtime() default to timezone.now() when no value is given
-----------------------------+--------------------------------------

Reporter: bmispelon | Owner: nobody
Type: New feature | Status: new
Component: Utilities | Version: 1.10
Severity: Normal | Resolution:

Keywords: | Triage Stage: Unreviewed
Has patch: 0 | Needs documentation: 0
Needs tests: 0 | Patch needs improvement: 0
Easy pickings: 0 | UI/UX: 0
-----------------------------+--------------------------------------

Comment (by aaugustin):

Replying to [comment:3 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 of `settings.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.

--
Ticket URL: <https://code.djangoproject.com/ticket/27082#comment:7>

Django

unread,
Aug 18, 2016, 10:19:18 AM8/18/16
to django-...@googlegroups.com
#27082: Make timezone.localtime() default to timezone.now() when no value is given
-----------------------------+--------------------------------------
Reporter: bmispelon | Owner: nobody
Type: New feature | Status: closed
Component: Utilities | Version: 1.10
Severity: Normal | Resolution: duplicate

Keywords: | Triage Stage: Unreviewed
Has patch: 0 | Needs documentation: 0
Needs tests: 0 | Patch needs improvement: 0
Easy pickings: 0 | UI/UX: 0
-----------------------------+--------------------------------------
Changes (by bmispelon):

* status: new => closed
* resolution: => duplicate


Comment:

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.

--
Ticket URL: <https://code.djangoproject.com/ticket/27082#comment:8>

Reply all
Reply to author
Forward
0 new messages