คุณจะแปลงวัตถุ time.struct_time เป็นวัตถุ datetime ได้อย่างไร


288

คุณจะแปลงtime.struct_timeวัตถุPython เป็นdatetime.datetimeวัตถุได้อย่างไร

ฉันมีห้องสมุดที่ให้ห้องสมุดแห่งแรกและห้องสมุดแห่งที่สองที่ต้องการห้องสมุดแห่งที่สอง

คำตอบ:


384

ใช้time.mktime ()เพื่อแปลง time tuple (เป็น localtime) เป็นวินาทีตั้งแต่ Epoch จากนั้นใช้datetime.fromtimestamp ()เพื่อรับอ็อบเจกต์ datetime

from datetime import datetime
from time import mktime

dt = datetime.fromtimestamp(mktime(struct))

45
โปรดทราบว่าสิ่งนี้ล้มเหลวก่อนปี 1900 คนทันสมัยคุณไม่เคยจำข้อ จำกัด นี้ได้!
mlissner

3
สิ่งนี้จะสูญเสียtm_isdstข้อมูลหรือไม่ ผมคิดว่าเป็นเช่นนั้นส่งผลให้วัตถุ datetime ยังคงไร้เดียงสาที่จะมีขอบเขตที่จะกลับมาNoneในวันที่.dst()แม้ว่าเป็นstruct.tm_isdst 1
n611x007

3
โดยปกติจะใช้งานได้ อย่างไรก็ตามมันจะล้มเหลวหาก time tuple นั้นเกินกว่าค่าที่ mktime ยอมรับเช่นค่า (1970, 1, 1, 0, 0, 0, 0, 0, 1, -1) ฉันพบสิ่งนี้หลังจากวิเคราะห์ส่วนหัว Date บนคำขอ HTTP ซึ่งส่งคืน tuple นี้
user3820547

3
@richvdh: มาตรฐาน C ระบุว่าmktime()ควรคำนึงtm_isdstถึงและ Python time.mktime()เรียกmktime()ใช้ฟังก์ชันC บน CPython mktime()สามารถเลือกเวลาท้องถิ่นที่ไม่ถูกต้องเมื่อมันไม่ชัดเจน (เช่นในช่วงปลายของ DST ( "ฤดูใบไม้ร่วงกลับ") การเปลี่ยนแปลง) ถ้าstruct.tm_isdstเป็น-1หรือถ้าmktime()บนแพลตฟอร์มที่กำหนดละเว้นการป้อนข้อมูล tm_isdstนอกจากนี้หากเขตเวลาท้องถิ่นมีอ็อฟเซ็ต utc ที่แตกต่างกันในอดีตและ C mktime()ไม่ได้ใช้ฐานข้อมูล tz เชิงประวัติที่สามารถให้ค่าอ็อฟเซ็ต utc เก่าได้ดังนั้นmktime()อาจส่งคืนค่าที่ไม่ถูกต้อง (เช่นชั่วโมง)
jfs

1
@naxa: ถ้าmktime()ไม่เพิกเฉยtm_isdstกับแพลตฟอร์มที่กำหนด (มันเป็นของฉัน) แล้วfromtimestamp()แน่นอนสูญเสียข้อมูล: วัตถุที่ไร้เดียงสาที่ถูก ส่งคืนซึ่งdatetimeแสดงถึงเวลาท้องถิ่นอาจไม่ชัดเจน (การประทับเวลา -> เวลาท้องถิ่นนั้นกำหนดไว้แล้ว) local time -> timestamp may be ambiguous e.g., during end-of-DST transition). Also, fromtimestamp () `อาจเลือกอ็อฟเซ็ต utc ที่ไม่ถูกต้องหากไม่ได้ใช้ฐานข้อมูล tz ที่ผ่านมา
jfs

123

แบบนี้:

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

3
อย่าลืมที่จะ #import time, datetime
jhwist

7
@jhwist - บางสิ่งที่คนสามารถเชื่อถือได้ที่จะคิดออกเอง :)
orip

14
@Ringling *และ**ไวยากรณ์ช่วยให้คุณสามารถขยายวัตถุชนิดที่มีค่าหรือมีค่าในการแยกอาร์กิวเมนต์ - มันเป็นหนึ่งในชิ้นโปรดของความน่ารักของ Python ดูdocs.python.org/2/tutorial/…สำหรับข้อมูลเพิ่มเติม
OrganicPanda

10
เพียงจำไว้ว่าสิ่งนี้จะให้ ValueError แก่คุณถ้า struct_time มี leapsecond เช่น:t=time.strptime("30 Jun 1997 22:59:60", "%d %b %Y %H:%M:%S"); datetime.datetime(*t[:6])
berdario

7
@berdario: การกลับมาค่าเข้ากันได้กับdatetime: เช่นที่จะยอมรับdatetime(*t[:5]+(min(t[5], 59),)) "2015-06-30 16:59:60 PDT"
jfs

37

นี่ไม่ใช่คำตอบสำหรับคำถามของคุณโดยตรง (ซึ่งได้รับคำตอบค่อนข้างดีอยู่แล้ว) อย่างไรก็ตามมีหลายครั้งที่กัดฉันบนพื้นฐานหลายครั้งฉันไม่สามารถความเครียดพอที่มันจะทำให้คุณมองอย่างใกล้ชิดในสิ่งที่เวลาของคุณ construct_time วัตถุให้กับเมื่อเทียบกับเขตเวลาอื่น ๆ อาจมี

สมมติว่าคุณมีทั้งวัตถุ time.struct_time และสตริงวันที่ / เวลาอื่นเปรียบเทียบทั้งสองและให้แน่ใจว่าคุณไม่สูญเสียข้อมูลและสร้างวัตถุ datetime ที่ไร้เดียงสาโดยไม่ตั้งใจเมื่อคุณสามารถทำเช่นนั้นได้

ตัวอย่างเช่นโมดูล feedparser ที่ยอดเยี่ยมจะส่งคืนฟิลด์ "เผยแพร่" และอาจส่งคืนวัตถุ time.struct_time ในฟิลด์ "publish_parsed" ของมัน:

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)

ตอนนี้ให้สังเกตสิ่งที่คุณได้รับจริงด้วยฟิลด์ "เผยแพร่"

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

โดยเคราของสตอลแมน ! ข้อมูลเขตเวลา!

ในกรณีนี้คนขี้เกียจอาจต้องการใช้โมดูล dateutil ที่ยอดเยี่ยมเพื่อเก็บข้อมูลเขตเวลา:

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()

ซึ่งทำให้เรา:

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

จากนั้นคุณสามารถใช้วัตถุ datetime ที่รับรู้เขตเวลาเพื่อทำให้เวลามาตรฐานเป็น UTC ทั้งหมดหรือสิ่งที่คุณคิดว่ายอดเยี่ยม


7
*_parsedฟิลด์ทั้งหมดจาก feedparsed จะถูกปรับให้เป็น UTC แล้วซึ่งสามารถตรวจสอบได้ในเอกสารการแยกวิเคราะห์วันที่เพื่อให้ซ้ำซ้อน
itorres

1
@itorres: ถ้าฉันเข้าใจคำตอบนี้ไม่เกี่ยวกับ normalizing เพื่อ UTC แต่เกี่ยวกับการเก็บข้อมูลเขตเวลาในdatetimeวัตถุที่หายไปเมื่อfeedparserแยกวิเคราะห์วันที่สตริงดิบ
davidag
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.