2008-10-22 30 views
54

Có một cách khá dễ dàng để chuyển đổi một đối tượng datetime vào một RFC 1123 (HTTP/1.1) ngày/giờ chuỗi, tức là một chuỗi với định dạngRFC 1123 Ngày đại diện bằng Python?

Sun, 06 Nov 1994 08:49:37 GMT 

Sử dụng strftime không làm việc, kể từ khi chuỗi là phụ thuộc vào miền địa phương. Tôi có phải xây dựng chuỗi bằng tay không?

Trả lời

75

Bạn có thể sử dụng wsgiref.handlers.format_date_time từ stdlib mà không dựa trên các thiết lập locale

from wsgiref.handlers import format_date_time 
from datetime import datetime 
from time import mktime 

now = datetime.now() 
stamp = mktime(now.timetuple()) 
print format_date_time(stamp) #--> Wed, 22 Oct 2008 10:52:40 GMT 

Bạn có thể sử dụng email.utils.formatdate từ stdlib không dựa trên cài đặt miền địa phương

from email.utils import formatdate 
from datetime import datetime 
from time import mktime 

now = datetime.now() 
stamp = mktime(now.timetuple()) 
print formatdate(
    timeval  = stamp, 
    localtime = False, 
    usegmt  = True 
) #--> Wed, 22 Oct 2008 10:55:46 GMT 

Nếu bạn có thể thiết lập các quá trình địa phương rộng sau đó bạn có thể làm:

import locale, datetime 

locale.setlocale(locale.LC_TIME, 'en_US') 
datetime.datetime.utcnow().strftime('%a, %d %b %Y %H:%M:%S GMT') 

Nếu bạn không muốn cài đặt quá trình locale rộng bạn có thể sử dụng Babeldate formating

from datetime import datetime 
from babel.dates import format_datetime 

now = datetime.utcnow() 
format = 'EEE, dd LLL yyyy hh:mm:ss' 
print format_datetime(now, format, locale='en') + ' GMT' 

Một cách thủ công sang định dạng nó giống hệt với wsgiref.handlers.format_date_time là:

def httpdate(dt): 
    """Return a string representation of a date according to RFC 1123 
    (HTTP/1.1). 

    The supplied date must be in UTC. 

    """ 
    weekday = ["Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun"][dt.weekday()] 
    month = ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", 
      "Oct", "Nov", "Dec"][dt.month - 1] 
    return "%s, %02d %s %04d %02d:%02d:%02d GMT" % (weekday, dt.day, month, 
     dt.year, dt.hour, dt.minute, dt.second) 
+1

Giải pháp này sẽ không hoạt động vì lý do được nêu trong câu hỏi: giờ nghỉ giải lao phụ thuộc vào miền địa phương. –

+0

đó là lý do tại sao bạn ocale.setlocale (locale.LC_TIME, 'en_US') –

+1

Và đó là lý do tại sao SO cần chỉ báo về thời điểm câu trả lời được chỉnh sửa. –

1

Bạn có thể đặt LC_TIME để buộc stftime() để sử dụng một miền địa phương cụ thể:

>>> locale.setlocale(locale.LC_TIME, 'en_US') 
'en_US' 
>>> datetime.datetime.now().strftime(locale.nl_langinfo(locale.D_T_FMT)) 
'Wed 22 Oct 2008 06:05:39 AM ' 
+0

Vâng, thiết lập (và đặt lại) locale.LC_TIME hoạt động, tất nhiên, nhưng điều này có nhược điểm, giống như hầu hết không an toàn luồng và tùy thuộc vào danh mục chuỗi dịch. Ngoài ra, locale.D_T_FMT không trả lại định dạng đúng với LC_TIME được đặt thành en_. –

+0

locale.D_T_FMT chỉ là một ví dụ. Bạn có thể chuyển bất kỳ định dạng nào bạn muốn để strftime(). –

30

Bạn có thể sử dụng hàm formatdate() từ tiêu chuẩn Python emai l module:

from email.utils import formatdate 
print formatdate(timeval=None, localtime=False, usegmt=True) 

Cung cấp cho thời gian hiện tại trong định dạng mong muốn:

Wed, 22 Oct 2008 10:32:33 GMT 

Trong thực tế, chức năng này làm nó "bằng tay" mà không sử dụng strftime()

1

Vâng, đây là một chức năng thủ công để định dạng nó:

def httpdate(dt): 
    """Return a string representation of a date according to RFC 1123 
    (HTTP/1.1). 

    The supplied date must be in UTC. 

    """ 
    weekday = ["Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun"][dt.weekday()] 
    month = ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", 
      "Oct", "Nov", "Dec"][dt.month - 1] 
    return "%s, %02d %s %04d %02d:%02d:%02d GMT" % (weekday, dt.day, month, 
     dt.year, dt.hour, dt.minute, dt.second) 
6

Nếu có ai đọc điều này đang làm việc trên Dja Dự án ngo, Django cung cấp chức năng django.utils.http.http_date(epoch_seconds).

from django.utils.http import http_date 

some_datetime = some_object.last_update 
response['Last-Modified'] = http_date(some_datetime.timestamp()) 
Các vấn đề liên quan