Làm thế nào để bạn chuyển đổi một đối tượng time.struct_time thành một đối tượng datetime?


288

Làm thế nào để bạn chuyển đổi một Python time.struct_time đối tượng thành một datetime.datetimeđối tượng?

Tôi có một thư viện cung cấp thư viện thứ nhất và thứ hai muốn có thư viện thứ hai.

Câu trả lời:


384

Sử dụng time.mktime () để chuyển đổi tuple thời gian (theo giờ địa phương) thành giây kể từ Epoch, sau đó sử dụng datetime.fromtimestamp () để lấy đối tượng datetime.

from datetime import datetime
from time import mktime

dt = datetime.fromtimestamp(mktime(struct))

45
Lưu ý rằng điều này thất bại trước năm 1900. Người hiện đại của bạn không bao giờ nhớ giới hạn này!
mlissner

3
điều này sẽ mất tm_isdstdữ liệu? Tôi nghĩ như vậy, kết quả datetime đối tượng vẫn còn ngây thơ đến mức để trở Nonevề .dst()ngay cả khi struct.tm_isdst1.
n611x007

3
Điều này thường sẽ làm việc. Tuy nhiên, nó sẽ thất bại nếu tuple thời gian vượt quá giá trị mktime chấp nhận, ví dụ cho giá trị (1970, 1, 1, 0, 0, 0, 0, 1, -1). Tôi đã gặp phải điều này sau khi phân tích tiêu đề Ngày trên một yêu cầu HTTP đã trả về bộ dữ liệu này.
dùng3820547

3
@richvdh: Tiêu chuẩn C chỉ định mktime()cần tính tm_isdstđến và Python time.mktime()gọi mktime()hàm C trên CPython. mktime()có thể chọn sai giờ địa phương khi không rõ ràng (ví dụ: trong quá trình chuyển đổi kết thúc DST ("quay lại") nếu struct.tm_isdst-1hoặc nếu mktime()trên nền tảng đã cho, bỏ qua đầu vào tm_isdst . Ngoài ra, nếu múi giờ cục bộ có offset utc khác nhau trong quá khứ và C mktime()không sử dụng cơ sở dữ liệu tz lịch sử có thể cung cấp các giá trị offset utc cũ thì mktime()cũng có thể trả về giá trị sai (ví dụ: một giờ).
JFS

1
@naxa: nếu mktime()không bỏ qua tm_isdsttrên nền tảng đã cho (nó không thuộc về tôi) thì fromtimestamp()chắc chắn sẽ mất thông tin: đối tượng ngây thơ được trả về datetimeđại diện cho giờ địa phương có thể mơ hồ (dấu thời gian -> giờ địa phương là xác định (nếu chúng ta bỏ qua giây nhuận) nhưng local time -> timestamp may be ambiguous e.g., during end-of-DST transition). Also, fromtimestamp () `có thể chọn sai bù utc nếu nó không sử dụng cơ sở dữ liệu tz lịch sử.
jfs

123

Như thế này:

>>> structTime = time.localtime()
>>> datetime.datetime(*structTime[:6])
datetime.datetime(2009, 11, 8, 20, 32, 35)

3
Đừng quên #import time, datetime
jhwist

7
@jhwist - một số điều mọi người có thể tin tưởng để tự mình tìm ra nó :)
orip

14
@rodling the ***cú pháp cho phép bạn mở rộng một đối tượng kiểu liệt kê hoặc dicty để tách các đối số - đó là một trong những phần yêu thích Python yêu thích của tôi. Xem docs.python.org/2/tutorial/m để biết thêm thông tin
OrganicPanda

10
Chỉ cần nhớ điều này sẽ cung cấp cho bạn một ValueError nếu struct_time có bước nhảy vọt, ví dụ:t=time.strptime("30 Jun 1997 22:59:60", "%d %b %Y %H:%M:%S"); datetime.datetime(*t[:6])
berdario

7
@berdario: để trả về các giá trị tương thích với datetime: datetime(*t[:5]+(min(t[5], 59),))vd, chấp nhận "2015-06-30 16:59:60 PDT".
JFS

37

Đây không phải là một câu trả lời trực tiếp cho câu hỏi của bạn (đã được trả lời khá tốt rồi). Tuy nhiên, đã nhiều lần cắn tôi về nguyên tắc cơ bản nhiều lần, tôi không thể nhấn mạnh đến mức nó sẽ khiến bạn phải nhìn kỹ vào những gì đối tượng time.struct_time của bạn đang cung cấp, so với những trường thời gian khác có thể có.

Giả sử bạn có cả đối tượng time.struct_time và một số chuỗi ngày / thời gian khác, hãy so sánh hai và chắc chắn rằng bạn không bị mất dữ liệu và vô tình tạo ra một đối tượng datetime ngây thơ, khi bạn có thể làm khác.

Ví dụ: mô-đun nguồn cấp dữ liệu tuyệt vời sẽ trả về trường "đã xuất bản" và có thể trả về một đối tượng time.struct_time trong trường "đã xuất bản_parsed" của nó:

time.struct_time(tm_year=2013, tm_mon=9, tm_mday=9, tm_hour=23, tm_min=57, tm_sec=42, tm_wday=0, tm_yday=252, tm_isdst=0)

Bây giờ hãy lưu ý những gì bạn thực sự nhận được với trường "đã xuất bản".

Mon, 09 Sep 2013 19:57:42 -0400

Bởi râu của Stallman ! Thông tin múi giờ!

Trong trường hợp này, người lười biếng có thể muốn sử dụng mô-đun dateutil tuyệt vời để giữ thông tin múi giờ:

from dateutil import parser
dt = parser.parse(entry["published"])
print "published", entry["published"])
print "dt", dt
print "utcoffset", dt.utcoffset()
print "tzinfo", dt.tzinfo
print "dst", dt.dst()

cung cấp cho chúng tôi:

published Mon, 09 Sep 2013 19:57:42 -0400
dt 2013-09-09 19:57:42-04:00
utcoffset -1 day, 20:00:00
tzinfo tzoffset(None, -14400)
dst 0:00:00

Sau đó, người ta có thể sử dụng đối tượng datetime nhận biết múi giờ để bình thường hóa mọi thời gian thành UTC hoặc bất cứ điều gì bạn nghĩ là tuyệt vời.


7
Tất cả các *_parsedtrường từ nguồn cấp dữ liệu đã được chuẩn hóa thành UTC như có thể được kiểm tra trong tài liệu phân tích ngày vì vậy điều này là không cần thiết.
22 giờ 44 phút

1
@itorres: Nếu tôi hiểu nó, câu trả lời này không phải là về việc chuẩn hóa UTC, mà là giữ thông tin múi giờ trong một datetimeđối tượng bị mất khi feedparserphân tích ngày chuỗi thô.
davidag
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.