Opened 6 years ago

Last modified 2 years ago

#12666 new New feature

Setting for sending email using localtime instead of UTC

Reported by: net147 Owned by: nobody
Component: Core (Mail) Version: 1.1
Severity: Normal Keywords:
Cc: Triage Stage: Accepted
Has patch: no Needs documentation: no
Needs tests: no Patch needs improvement: no
Easy pickings: no UI/UX: no

Description (last modified by ramiro)

I would like to be able to send emails using local time in the Date header instead of UTC by default.

Changes needed (based on Django 1.1.1):

  • django/conf/global_settings.py:
    • Add "EMAIL_USE_LOCALTIME = False" (won't sent using local time by default unless you explicitly enable it)
  • django/core/mail.py:
    • Change "msg['Date'] = formatdate()" to "msg['Date'] = formatdate(localtime=settings.EMAIL_USE_LOCALTIME)"

Change History (12)

comment:1 follow-up: Changed 6 years ago by russellm

  • Needs documentation unset
  • Needs tests unset
  • Patch needs improvement unset
  • Resolution set to wontfix
  • Status changed from new to closed

Is there a particularly compelling reason to send mail with headers in local time, rather than against UTC?

Marking wontfix because I'm not aware of any particular advantage. If you can provide any evidence that it's the right/best practice thing to do, this shouldn't be configurable - it should be turned on by default.

comment:2 Changed 5 years ago by ramiro

  • Description modified (diff)

(re-formatted description)

comment:3 Changed 5 years ago by ramiro

#13535 proposed the same (without a setting) and contained a patch.

comment:4 in reply to: ↑ 1 Changed 5 years ago by geofft

  • Resolution wontfix deleted
  • Status changed from closed to reopened

ramiro: thanks, I searched but couldn't find a prior ticket.

Replying to russellm:

Marking wontfix because I'm not aware of any particular advantage. If you can provide any evidence that it's the right/best practice thing to do, this shouldn't be configurable - it should be turned on by default.

The e-mail Date header is defined to include both a time and a timezone offset indicating the local time of the sender. As it is, we're effectively only sending one of those two and making the second one useless at best, and possibly actively misleading. This is why I attached a patch to change it unconditionally and not make it configurable.

Practically speaking, my e-mail client (alpine) displays times in the timezone of the Date header without converting them to local time. I'm generally used to this behavior, so it confused me to see an e-mail from a Django server in the same city (and building) as me send with a time several hours ahead, causing it to display in the index view as "Tomorrow", since it was past midnight UTC.

Personally, I'm also inclined to believe that Python's standard libraries default to localtime=False because they're generally just bad at handling time zones and try to pretend that they don't exist. I'm not sure I see arguments for why formatdate should be defaulting to localtime=False, and I really don't see arguments for why Django wants that setting past that it's the default.

comment:5 follow-up: Changed 5 years ago by lukeplant

I'm not convinced it is the right thing to do. I have sites that are 'British' (i.e. serve almost entirely a British audience who live in GMT time), but the server happens to be in the States. It would just as 'misleading' to have e-mails that come from a non-British time zone (whereas UTC is kind of 'neutral').

Strictly speaking, I guess the time zone ought to be the time zone of the 'sender'. But who is the sender? If it's a contact form, the sender is the person who enters the message - we have no idea what his/her time zone is. In the case of an automated message sent by the webserver, it's debatable whether the machine 'lives in' the time zone the machine happens to be located in. It's also probably not desirable for the behaviour of a web site to change if I happen to move it to a different server.

comment:6 Changed 5 years ago by kmtracey

  • Triage Stage changed from Unreviewed to Design decision needed

Replying to geofft:

The e-mail Date header is defined to include both a time and a timezone offset indicating the local time of the sender.

Note when making statements like this, it is helpful to include a reference to whatever source you are considering responsible for defining such things. In this case I'd guess the relevant standard is RFC 2822. It states in section 3.3 that: "The date and time-of-day SHOULD express local time." This same section also sates:

   Though "-0000" also indicates Universal Time, it is
   used to indicate that the time was generated on a system that may be
   in a local time zone other than Universal Time and therefore
   indicates that the date-time contains no information about the local
   time zone.

Which sounds to me like the standard explicitly allows for specifying dates/times using only an absolute value, with no indication of what local time may be. This "-0000" spec is what Django is currently sending, and thus per the standard I think what it is doing is technically correct. Programs which are inferring anything about the local time of the sender when "-0000" has been specified are the ones that are, technically, doing something wrong. (Gmail's labs "Sender Time Zone" extension falls into this category.)

I am not sure what the right answer is, but I'm leaning towards thinking Django ought to be specifying localtime=True here. Though Luke has a good point about the server's time zone not necessarily having any relevance, for some servers the local time may in fact be relevant, and it is a bit annoying that it is not reflected in the date headers included in mail.

comment:7 in reply to: ↑ 5 ; follow-up: Changed 5 years ago by geofft

Replying to lukeplant:

I'm not convinced it is the right thing to do. I have sites that are 'British' (i.e. serve almost entirely a British audience who live in GMT time), but the server happens to be in the States. It would just as 'misleading' to have e-mails that come from a non-British time zone (whereas UTC is kind of 'neutral').

Isn't this what TIME_ZONE in settings.py is for?

In [3]: settings.TIME_ZONE
Out[3]: 'America/Chicago'

In [4]: formatdate(localtime=True)
Out[4]: 'Fri, 14 May 2010 12:33:04 -0500'
In [3]: settings.TIME_ZONE
Out[3]: 'Europe/London'

In [4]: formatdate(localtime=True)
Out[4]: 'Fri, 14 May 2010 18:33:35 +0100'

Replying to kmtracey:

Which sounds to me like the standard explicitly allows for specifying dates/times using only an absolute value, with no indication of what local time may be. This "-0000" spec is what Django is currently sending, and thus per the standard I think what it is doing is technically correct.

Oh, good call, and sorry for not double-checking the RFC. That said, I still think it would be more useful to send "information about the local time zone" than not to, especially given that there is a TIME_ZONE variable. (The part that confused me here the most was that TIME_ZONE was set but not used.)

comment:8 in reply to: ↑ 7 Changed 5 years ago by lukeplant

Replying to geofft:

Isn't this what TIME_ZONE in settings.py is for?

In [3]: settings.TIME_ZONE
Out[3]: 'Europe/London'

In [4]: formatdate(localtime=True)
Out[4]: 'Fri, 14 May 2010 18:33:35 +0100'

That's a very good point. But now I've got to go and work out why I am not seeing that behaviour in the e-mails I receive, even though I have settings.TIME_ZONE = 'Europe/London' :-(

comment:9 Changed 5 years ago by mtredinnick

  • Triage Stage changed from Design decision needed to Accepted

Russ and I talked about this. It sounds like broken clients. To make things easier for people to change in the cases where a lot of their users have said clients, we'll make formatdate() a method on the Email class that, by default, calls the email utils' formatdate(). Then people can subclass the Email class (or just supply the date header, which you can already do) and put whatever they like there. Current behaviour is technically correct however and remains the default.

comment:10 Changed 4 years ago by mattmcc

  • Severity set to Normal
  • Type set to New feature

comment:11 Changed 4 years ago by Andrey Mitroshin <mit@…>

  • Easy pickings unset
  • UI/UX unset

In django/core/mail/message.py (Django 1.3.1)

msg['Date'] = formatdate()

There is no localtime=True and emails are sending using UTC
When I correct django/core/mail/message.py to

msg['Date'] = formatdate(localtime=True) 

Then emails are being sent with correct Date header (using local time with timezone)

EDIT(aaugustin): fixed formatting

Last edited 4 years ago by aaugustin (previous) (diff)

comment:12 Changed 2 years ago by aaugustin

  • Status changed from reopened to new
Note: See TracTickets for help on using tickets.
Back to Top