2009-02-08 39 views
22

Theo dõi từ câu hỏi trước của tôi, Python time to age, tôi đã gặp phải vấn đề liên quan đến múi giờ và không phải lúc nào cũng là "+0200". Vì vậy, khi strptime cố gắng phân tích nó như vậy, nó ném lên một ngoại lệ.Thời gian Python đến tuổi, phần 2: múi giờ

Tôi đã nghĩ đến việc chỉ cắt +0200 bằng [: -6] hoặc bất kỳ thứ gì, nhưng có cách nào thực sự để làm điều này với strptime không?

Tôi đang sử dụng Python 2.5.2 nếu nó quan trọng.

>>> from datetime import datetime 
>>> fmt = "%a, %d %b %Y %H:%M:%S +0200" 
>>> datetime.strptime("Tue, 22 Jul 2008 08:17:41 +0200", fmt) 
datetime.datetime(2008, 7, 22, 8, 17, 41) 
>>> datetime.strptime("Tue, 22 Jul 2008 08:17:41 +0300", fmt) 
Traceback (most recent call last): 
    File "<stdin>", line 1, in <module> 
    File "/usr/lib/python2.5/_strptime.py", line 330, in strptime 
    (data_string, format)) 
ValueError: time data did not match format: data=Tue, 22 Jul 2008 08:17:41 +0300 fmt=%a, %d %b %Y %H:%M:%S +0200 

Trả lời

28

New in version 2.6.

For a naive object, the %z and %Z format codes are replaced by empty strings.

Có vẻ như điều này chỉ được triển khai trong> = 2,6 và tôi nghĩ bạn phải phân tích cú pháp theo cách thủ công.

Tôi không thể nhìn thấy một giải pháp khác hơn để loại bỏ các dữ liệu múi giờ:

from datetime import timedelta,datetime 
try: 
    offset = int("Tue, 22 Jul 2008 08:17:41 +0300"[-5:]) 
except: 
    print "Error" 

delta = timedelta(hours = offset/100) 

fmt = "%a, %d %b %Y %H:%M:%S" 
time = datetime.strptime("Tue, 22 Jul 2008 08:17:41 +0200"[:-6], fmt) 
time -= delta 
+0

Khi một đạt được, cảm ơn gs và cũng David :) Tôi đoán tôi sẽ chỉ phải chặt đầu, không muốn dựa vào 2.6 cho việc này. – Ashy

+0

Không hoạt động đối với các múi giờ như Venezuela: -0430 – chachan

+0

@chachan: Nhưng điều chỉnh một cách trivially. –

1

Theo như tôi biết, strptime() không nhận dạng được mã múi giờ. Nếu bạn biết rằng chuỗi luôn luôn kết thúc với một đặc tả múi giờ của biểu mẫu đó (+ hoặc - theo sau là 4 chữ số), chỉ cần cắt nó ra và phân tích nó theo cách thủ công có vẻ như một điều hoàn toàn hợp lý để làm.

0

Dường như% Z tương ứng với tên múi giờ, không offsets.

Ví dụ, đưa ra:

>>> format = '%a, %d %b %Y %H:%M:%S %Z' 

tôi có thể phân tích cú pháp:

>>> datetime.datetime.strptime('Tue, 22 Jul 2008 08:17:41 GMT', format) 
datetime.datetime(2008, 7, 22, 8, 17, 41) 

Mặc dù có vẻ như nó không làm bất cứ điều gì với múi giờ, chỉ đơn thuần là quan sát rằng nó tồn tại và có giá trị :

>>> datetime.datetime.strptime('Tue, 22 Jul 2008 08:17:41 NZDT', format) 
datetime.datetime(2008, 7, 22, 8, 17, 41) 

Tôi cho rằng nếu bạn muốn, bạn có thể xác định vị trí ánh xạ các tên, chuyển đổi đầu vào, và sau đó phân tích nó. Nó có thể đơn giản hơn để chỉ cắt ngắn đầu vào của bạn, mặc dù.

+0

% Z là múi giờ dưới dạng tên,% z tính theo giờ. –

+6

Nếu tôi cố gắng sử dụng% z trong strptime, tôi nhận được: ValueError: 'z' là một chỉ thị không hợp lệ ở định dạng '% z' –

40

is there a real way to do this with strptime?

Không, nhưng vì định dạng của bạn dường như là một ngày RFC822-gia đình, bạn có thể đọc nó dễ dàng hơn nhiều bằng cách sử dụng thư viện email thay vì:

>>> import email.utils 
>>> email.utils.parsedate_tz('Tue, 22 Jul 2008 08:17:41 +0200') 
(2008, 7, 22, 8, 17, 41, 0, 1, 0, 7200) 

(7200 = múi giờ bù đắp từ UTC ở giây)

+0

Thú vị, nhưng sau đó tôi có thể làm cách nào khác nhau giữa hai ngày một cách dễ dàng? – Ashy

+6

Nếu bạn đang sử dụng datetime, hãy tạo datetime bằng cách sử dụng sáu giá trị đầu tiên của bộ kết quả, sau đó bù cho vùng bằng cách trừ một delta của giá trị cuối cùng, ví dụ: “Datetime.datetime (* a [: 6]) - datetime.timedelta (giây = a [-1])”. Sau đó tiến hành so sánh datetimes như trong câu hỏi trước. – bobince

+2

Nếu bạn đang sử dụng ‘thời gian’ thuần tuý cũ, hãy sử dụng mktime() để chuyển từ một bộ tất cả trừ giá trị cuối cùng thành dấu thời gian số, sau đó trừ giá trị cuối cùng. Lưu ý rằng mktime cung cấp cho bạn một dấu thời gian dựa trên múi giờ máy chủ cục bộ của bạn chứ không phải UTC, nhưng điều đó không quan trọng nếu bạn chỉ đang so sánh hai dấu thời gian. – bobince

18

Bạn có thể sử dụng thư viện dateutil mà là rất hữu ích:

from datetime import datetime 
from dateutil.parser import parse 

dt = parse("Tue, 22 Jul 2008 08:17:41 +0200") 
## datetime.datetime(2008, 7, 22, 8, 17, 41, tzinfo=tzoffset(None, 7200)) <- dt 

print dt 
2008-07-22 08:17:41+02:00 
+0

Tôi đã sử dụng giải pháp này. –

+0

Tôi đã không nhận thức được giải pháp này, chỉ cần thử nghiệm: hoạt động thực sự tuyệt vời! – user1151446

Các vấn đề liên quan