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 Aymeric Augustin, 8 years ago

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.

comment:2 by Baptiste Mispelon, 8 years ago

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

comment:3 by Jon Dufresne, 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 Aymeric Augustin, 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:5 by Baptiste Mispelon, 8 years ago

Are you talking about #25181 ?

comment:6 by Aymeric Augustin, 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.)

in reply to:  3 comment:7 by Aymeric Augustin, 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 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.

comment:8 by Baptiste Mispelon, 8 years ago

Resolution: duplicate
Status: newclosed

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.

Note: See TracTickets for help on using tickets.
Back to Top