18

I'm writing a web-based email client in Python and a question has arisen about which time zone the "Date" header of an email should be represented as when sending.

RFC 2822 states in section 3.3 that:

The date and time-of-day SHOULD express local time.

This seems ambiguous to me; the question is the local time of who? The email server, or the sender? Naturally I'd assume the sender (who could be in any time zone, and can be changed in their account preferences). Further confusion arose when I looked Python's email.utils.formatdate function which seems to only offer two alternatives: UTC or local time (of the server). To me there doesn't appear to be any option of specifying an alternate timezone, or am I missing something?

Passing a timeval to formatdate using time.mktime(senders_tz_aware_now_datetime.timetuple()) results in a UTC date string, which feels wrong given what the RFC says above.

So which timezone should "Date" be, and does any standard function exist to create the appropriate date string?

kuhnza
  • 731
  • 1
  • 5
  • 15
  • I believe this thread ( https://stackoverflow.com/a/16509278/3223785 ) might help to better understand the current thread. These are subjects with a strong connection. – Eduardo Lucio Jan 03 '23 at 13:55

3 Answers3

12

If you want to adhere to the RFC, pass localtime=True which returns a date string with the local time and the right time zone (assuming you have it set up correctly).

>>> email.utils.formatdate(localtime=True)
'Mon, 07 May 2012 12:09:16 -0700'

Without localtime=True you get a date string representing UTC time:

>>> email.utils.formatdate()
'Mon, 07 May 2012 19:08:55 -0000'

-0000 apparently indicates UTC, although the RFC specifically recommends using +0000. Not sure if this is a bug in email.utils.

Here's the relevant python documentation:

Optional localtime is a flag that when True, interprets timeval, and returns a date relative to the local timezone instead of UTC, properly taking daylight savings time into account. The default is False meaning UTC is used.

spinlok
  • 3,561
  • 18
  • 27
  • 1
    Thanks, of course this is what we had initially thought would do the trick. Unfortunately your answer raises the very question which has me stumped: what is "the right time zone"? Setting `localtime=True` returns the time zone of the server, not the sender. Hence my question, should it be the local time zone of the server or the sender? One would assume that timezone of the sender is the correct thing to do. However in this case I cannot see formatdate providing the necessary functionality to do this. – kuhnza May 07 '12 at 19:16
  • 3
    It doesn't matter what timezone the sender is in as long as you generate a consistent timestamp that represents the time at which the email was sent. It's up to the receiver's client to interpret it correctly. That is why @Sorin suggested going with UTC which is the simplest way. – spinlok May 07 '12 at 19:21
  • I agree that it shouldn't matter but it bothers me that the RFC says that it SHOULD appear as local time. – kuhnza May 07 '12 at 19:31
  • How would you know the clients' time zone? What if the client that registered yesterday from London a day later is in Japan? Local time on the server side can only mean local server time, not local client time. What if the mail is sent to 10 clients in 10 time zones, which would you use? (+1 on use UTC, your program won't break even if you forget to update your timezone database) – Doncho Gunchev May 17 '12 at 15:43
4

Just use UTC and you'll be happier.

Thats's what is happening when specifications are using terms like SHOULD. I think that both SHOULD may be banned from specifications because they are always creating unneeded complexity.

Using UTC is perfectly valid.

sorin
  • 161,544
  • 178
  • 535
  • 806
  • That's not going to do it, I'm converting a time zone aware datetime object using the timetuple method which means is_dst is already set. Also it doesn't answer my question about what the correct date time representation is. – kuhnza May 07 '12 at 18:51
  • 2
    Changed my mind, go the easy way and you'll have time to drink a beer in the evening. – sorin May 07 '12 at 19:08
  • 2
    Haha I like your style. Still, I'd like to get some sort of idea of how this is commonly handled because I imagine it has implications across a range of email clients that I've never heard of let alone possess the time or resources to test with. – kuhnza May 07 '12 at 19:18
  • 1
    I doubt you will see clients not being able to cope with UTC. – sorin May 07 '12 at 19:24
2

This comes up as a top result when googling "email client local time"; unfortunately, the two answers and accompanying comments barely address the python implementation, and fail completely to speak to the subject line (which is what's feeding the google response).

The RFC is unambiguous because it's obvious: the "^Date: " header is local at the moment it is written. The mail client generally writes the "^Date: " header (in any of the many implementations I've dealt with). For most (sanely configured) clients this will be the local time as reported by the client's OS.

In the case of webmail, the local time could be supplied by the user agent (which commonly gets its local time from the OS in turn). More typically it would be set by the user within the web application (a la gmail).

Importantly, if you "follow the RFC" (probably a good idea for a network protocol), the resultant behavior on RECEIVING clients will generally be to show the date the mail was sent as seen by the sender. This is the whole point of "SHOULD" in the RFC. I don't want to see UTC when trying to figure out what time a colleague sent an email; I want their local time. That way, I can figure out the time difference in one step (their local time to mine), not two (their local time to UTC to my local time). I also get immediate clues about the context of their communications (was it night? working hours? etc).

ccy
  • 51
  • 3