From 3dd9e461618b0964312fa3c649cf03c7bfe27827 Mon Sep 17 00:00:00 2001 From: Anthony Baxter Date: Mon, 11 Oct 2004 13:53:08 +0000 Subject: Added a usegmt flag to email.Utils.formatdate - this allows it to be used to replace rfc822.formatdate for protocols like HTTP (where 'GMT' must be the timezone string). --- Doc/lib/emailutil.tex | 7 ++++++- Lib/email/Utils.py | 11 +++++++++-- Lib/email/test/test_email.py | 9 +++++++++ Lib/urllib.py | 4 ++-- Lib/urllib2.py | 4 ++-- 5 files changed, 28 insertions(+), 7 deletions(-) diff --git a/Doc/lib/emailutil.tex b/Doc/lib/emailutil.tex index c41f066..b93a2b9 100644 --- a/Doc/lib/emailutil.tex +++ b/Doc/lib/emailutil.tex @@ -84,7 +84,7 @@ changes in daylight savings time, though not worth worrying about for common use. \end{funcdesc} -\begin{funcdesc}{formatdate}{\optional{timeval\optional{, localtime}}} +\begin{funcdesc}{formatdate}{\optional{timeval\optional{, localtime}\optional{, usegmt}}} Returns a date string as per \rfc{2822}, e.g.: \begin{verbatim} @@ -99,6 +99,11 @@ Optional \var{localtime} is a flag that when \code{True}, interprets \var{timeval}, and returns a date relative to the local timezone instead of UTC, properly taking daylight savings time into account. The default is \code{False} meaning UTC is used. + +Optional \var{usegmt} is a flag that when \code{True}, outputs a +date string with the timezone as an ascii string \code{GMT}, rather +than a numeric \code{-0000}. This is needed for some protocols (such +as HTTP). This only applies when \var{localtime} is \code{False} \end{funcdesc} \begin{funcdesc}{make_msgid}{\optional{idstring}} diff --git a/Lib/email/Utils.py b/Lib/email/Utils.py index e786d26..f210eec 100644 --- a/Lib/email/Utils.py +++ b/Lib/email/Utils.py @@ -103,7 +103,7 @@ ecre = re.compile(r''' -def formatdate(timeval=None, localtime=False): +def formatdate(timeval=None, localtime=False, usegmt=False): """Returns a date string as specified by RFC 2822, e.g.: Fri, 09 Nov 2001 01:08:47 -0000 @@ -114,6 +114,10 @@ def formatdate(timeval=None, localtime=False): 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. + + Optional argument usegmt means that the timezone is written out as + an ascii string, not numeric one (so "GMT" instead of "+0000"). This + is needed for HTTP, and is only used when localtime==False. """ # Note: we cannot use strftime() because that honors the locale and RFC # 2822 requires that day and month names be the English abbreviations. @@ -138,7 +142,10 @@ def formatdate(timeval=None, localtime=False): else: now = time.gmtime(timeval) # Timezone offset is always -0000 - zone = '-0000' + if usegmt: + zone = 'GMT' + else: + zone = '-0000' return '%s, %02d %s %04d %02d:%02d:%02d %s' % ( ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun'][now[6]], now[2], diff --git a/Lib/email/test/test_email.py b/Lib/email/test/test_email.py index f2aa8d7..745260e 100644 --- a/Lib/email/test/test_email.py +++ b/Lib/email/test/test_email.py @@ -2037,6 +2037,15 @@ class TestMiscellaneous(unittest.TestCase): Utils.parsedate(Utils.formatdate(now, localtime=True))[:6], time.localtime(now)[:6]) + def test_formatdate_usegmt(self): + now = time.time() + self.assertEqual( + Utils.formatdate(now, localtime=False), + time.strftime('%a, %d %b %Y %H:%M:%S -0000', time.gmtime(now))) + self.assertEqual( + Utils.formatdate(now, localtime=False, usegmt=True), + time.strftime('%a, %d %b %Y %H:%M:%S GMT', time.gmtime(now))) + def test_parsedate_none(self): self.assertEqual(Utils.parsedate(''), None) diff --git a/Lib/urllib.py b/Lib/urllib.py index 2969ef0..e2f01c5 100644 --- a/Lib/urllib.py +++ b/Lib/urllib.py @@ -410,7 +410,7 @@ class URLopener: def open_local_file(self, url): """Use local file.""" - import mimetypes, mimetools, rfc822, StringIO + import mimetypes, mimetools, email.Utils, StringIO host, file = splithost(url) localname = url2pathname(file) try: @@ -418,7 +418,7 @@ class URLopener: except OSError, e: raise IOError(e.errno, e.strerror, e.filename) size = stats.st_size - modified = rfc822.formatdate(stats.st_mtime) + modified = email.Utils.formatdate(stats.st_mtime, usegmt=True) mtype = mimetypes.guess_type(url)[0] headers = mimetools.Message(StringIO.StringIO( 'Content-Type: %s\nContent-Length: %d\nLast-modified: %s\n' % diff --git a/Lib/urllib2.py b/Lib/urllib2.py index f1c94e1..644b380 100644 --- a/Lib/urllib2.py +++ b/Lib/urllib2.py @@ -99,7 +99,6 @@ import os import posixpath import random import re -import rfc822 import sha import socket import sys @@ -1129,12 +1128,13 @@ class FileHandler(BaseHandler): # not entirely sure what the rules are here def open_local_file(self, req): + import email.Utils host = req.get_host() file = req.get_selector() localfile = url2pathname(file) stats = os.stat(localfile) size = stats.st_size - modified = rfc822.formatdate(stats.st_mtime) + modified = email.Utils.formatdate(stats.st_mtime, usegmt=True) mtype = mimetypes.guess_type(file)[0] headers = mimetools.Message(StringIO( 'Content-type: %s\nContent-length: %d\nLast-modified: %s\n' % -- cgit v0.12