แปลง python datetime เป็น epoch ด้วย strftime


209

ฉันมีเวลาเป็น UTC ซึ่งฉันต้องการจำนวนวินาทีตั้งแต่ยุค

ฉันกำลังใช้ strftime เพื่อแปลงเป็นจำนวนวินาที ยกตัวอย่างวันที่ 1 เมษายน 2555

>>>datetime.datetime(2012,04,01,0,0).strftime('%s')
'1333234800'

วันที่ 1 เมษายน 2012 UTC จากยุคคือ 1333238400 แต่สิ่งนี้จะส่งคืน 1333234800 ซึ่งต่างจาก 1 ชั่วโมง

ดังนั้นดูเหมือนว่า strftime นั้นจะคำนึงถึงเวลาของระบบของฉันและใช้การเปลี่ยนเขตเวลาในบางแห่ง ฉันคิดว่า datetime ไร้เดียงสาหมดจด?

ฉันจะหลีกเลี่ยงสิ่งนั้นได้อย่างไร หากเป็นไปได้หลีกเลี่ยงการนำเข้าไลบรารีอื่น ๆ ยกเว้นมาตรฐาน (ฉันมีข้อกังวลเกี่ยวกับการพกพา)


ที่เกี่ยวข้อง: การแปลง datetime.date เป็นเวลา UTC ใน Python
jfs

11
ฉันเป็นคนเดียวที่สังเกตว่าคุณใช้ตัวอักษรฐานแปดในตัวเลขหรือไม่?
Fish Monitor


3
ใหม่กว่า Python 3.3+ มีdatetime.datetime.timestamp(datetime.datetime.utcnow())
MarkHu

คำตอบ:


389

ถ้าคุณต้องการแปลง python datetime เป็นวินาทีตั้งแต่ epoch คุณสามารถทำได้อย่างชัดเจน:

>>> (datetime.datetime(2012,04,01,0,0) - datetime.datetime(1970,1,1)).total_seconds()
1333238400.0

ใน Python 3.3+ คุณสามารถใช้timestamp()แทน:

>>> datetime.datetime(2012,4,1,0,0).timestamp()
1333234800.0

ทำไมคุณไม่ควรใช้ datetime.strftime('%s')

งูหลามไม่จริงสนับสนุน% s เป็นอาร์กิวเมนต์ strftime (ให้ถ้าคุณตรวจสอบที่http://docs.python.org/library/datetime.html#strftime-and-strptime-behaviorมันไม่ได้อยู่ในรายการ) เพียงอย่างเดียว เหตุผลก็คือการทำงานเป็นเพราะหลามส่งข้อมูลไปยัง strftime ของระบบของคุณซึ่งใช้เขตเวลาท้องถิ่นของคุณ

>>> datetime.datetime(2012,04,01,0,0).strftime('%s')
'1333234800'

7
ฉันบ้าลองคิดดูว่าทำไมฉันถึงเห็น strftime ("% s") มาก แต่มันไม่ได้อยู่ในเอกสาร ขอบคุณสำหรับสิ่งนี้!
Jonathan Vanasco

54
อย่าใช้.strftime("%s"): ไม่รองรับ, มันไม่สามารถพกพาได้, มันอาจสร้างผลลัพธ์ที่ไม่ถูกต้องสำหรับวัตถุ datetime ที่รับรู้ได้, มันจะล้มเหลวหากอินพุตอยู่ใน UTC (ตามคำถาม) แต่เขตเวลาท้องถิ่นไม่ใช่ UTC
jfs

2
@earthmeLon การถ่ายคร่อมของคุณผิด Timedeltas (ทำโดยการลบสองชุดข้อมูล) มีจำนวนรวมทั้งหมด แต่ชุดข้อมูลไม่มี
jleahy

2
นี่ใช้ไม่ได้กับฉัน:AttributeError: 'datetime.timedelta' object has no attribute 'total_seconds'
Michael

3
@Michael ฟังก์ชั่นใหม่ใน Python 2.7 คุณต้องใช้เวอร์ชั่นที่เก่ากว่า สำหรับรุ่นก่อน 2.7 td.seconds + td.days*24*3600ที่คุณสามารถทำได้ ส่วนนี้จะละทิ้งไมโครวินาที
jleahy

100

ฉันมีปัญหาร้ายแรงกับเขตเวลาและเช่นนั้น วิธีที่ Python จัดการกับสิ่งต่าง ๆ ที่เกิดขึ้นนั้นค่อนข้างสับสน (สำหรับฉัน) ทุกอย่างทำงานได้ดีโดยใช้โมดูลปฏิทิน (ดูลิงก์1 , 2 , 3และ4 )

>>> import datetime
>>> import calendar
>>> aprilFirst=datetime.datetime(2012, 04, 01, 0, 0)
>>> calendar.timegm(aprilFirst.timetuple())
1333238400

7
+1 เพราะเป็นคำตอบเดียวที่ใช้ได้กับอินพุตในคำถาม
jfs

พกพานี้หรือไม่
benjaminz

1
สิ่งนี้ควรถูกทำเครื่องหมายเป็นคำตอบที่ถูกต้องเนื่องจากสิ่งนี้จะตอบข้อกังวลในคำถาม vnice kudos
Leo Prince

2
สิ่งนี้ใช้งานได้ แต่ให้สังเกตคำถามที่ระบุไว้: "ฉันมีเวลาเป็น UTC" วิธีนี้จะใช้เขตเวลาท้องถิ่นของระบบเสมอ ไม่มีวิธีระบุเขตเวลา หากaprilFirstในตัวอย่างนี้เป็นอินสแตนซ์ 'ระวัง' และใช้เขตเวลาที่แตกต่างจากเขตเวลาของระบบผลลัพธ์จะไม่ถูกต้อง (เขตเวลาจะหายไปจากการtimetuple()โทร) เพื่อให้ได้คำตอบที่ถูกต้องสำหรับวันที่ 'ทราบ' คุณสามารถใช้awaredt.timestamp()กับ Python 3 ล่าสุดสำหรับ Python 2 มันยากกว่า วิธีหนึ่งคือการใช้arrowห้องสมุด arrow.get(awaredt).timestampจะทำให้ถูกต้อง
Adam Williamson

1
จุดที่ดี @ AdamWilliamson แต่รหัสในตัวอย่างไม่ได้แปลเป็นdatetimeวัตถุดังนั้นฉันคิดว่า "ฉันมีเวลาใน UTC"หมายความว่า OP มีdatetimeวัตถุที่ไม่รู้จักซึ่งสันนิษฐานว่าเป็น UTC ซึ่งเขาต้องการ เพื่อรับepoch(ถ้าdatetimeเกิดขึ้นเป็น TZ - ตระหนักถึงสิ่งนี้อาจเปลี่ยนแปลงสิ่งต่าง ๆ ) นอกจากนี้โปรดทราบว่าคำตอบนี้มีอายุเกือบ 8 ปีและมีหลายสิ่งหลายอย่างเกิดขึ้นตั้งแต่ ( arrowเผยแพร่ในปี 2013 เป็นต้น)
BorrajaX

35
import time
from datetime import datetime
now = datetime.now()

time.mktime(now.timetuple())

1
มันเป็นวิธีที่ไม่ถูกต้องในการเขียนtime.time()( mktime()อาจล้มเหลวในระหว่างการเปลี่ยน DST ในขณะที่time.time()ยังคงทำงาน) และจะไม่ตอบคำถามนอกจากเขตเวลาท้องถิ่นคือ UTC (ข้อมูลในคำถามเป็น UTC) แม้ว่าการป้อนข้อมูลจะแสดงเวลาท้องถิ่นก็mktime()อาจล้มเหลวสำหรับวันที่ผ่านมา / อนาคตหากไม่ใช้ฐานข้อมูล tz และหากเขตเวลาท้องถิ่นอาจมีการลดเวลาที่แตกต่างกันในช่วงหลายปีเช่นยุโรป / มอสโกในปี 2553-2558 - - ใช้เวลา UTC (ตามคำถาม) หรือวัตถุวันที่และเวลาที่ทราบเขตเวลาแทน
jfs

here're ปัญหามากขึ้นด้วยการแปลงเป็นเวลาท้องถิ่น (เช่นส่งกลับโดย.now()) ไปยุคประทับเวลา (ส่งกลับโดยmktime() ) ถ้าคุณอ่านมัน; คุณเข้าใจว่าทำไมการป้อนข้อมูล UTC (ใช้ในคำถาม) จึงเป็นที่นิยมมากกว่าวัตถุไร้เดียงสาที่ใช้แทนเวลาท้องถิ่น
jfs

14
import time
from datetime import datetime
now = datetime.now()

# same as above except keeps microseconds
time.mktime(now.timetuple()) + now.microsecond * 1e-6

(ขออภัยมันไม่ให้ความเห็นกับคำตอบที่มีอยู่)


นั่นเป็นเพราะ time.mktime ไม่ได้คำนึงถึงส่วนที่เป็นไมโครวินาทีใช่ไหม?
Eduardo

1
แก้ไข. โครงสร้าง tuple time (อ้างอิงจาก C strut) ไม่มีที่ว่างสำหรับไมโครวินาทีดังนั้นเราจำเป็นต้องดึงข้อมูลจากวัตถุ datetime และเพิ่มในตอนท้าย
Charles Plager


บนเครื่องของฉันทำงานอย่างถูกต้องแม้ว่าเขตเวลาของฉันคือ ET
Charles Plager

1
สิ่งนี้จะให้คุณประทับเวลาที่แตกต่างกันในระบบที่แตกต่างกันตามเวลาท้องถิ่นของระบบ
Yousaf

6

หากคุณต้องการเวลาประทับในเวลา unix / epoch หนึ่งบรรทัดนี้จะทำงาน:

created_timestamp = int((datetime.datetime.now() - datetime.datetime(1970,1,1)).total_seconds())
>>> created_timestamp
1522942073L

และขึ้นอยู่กับdatetime งานใน python2 และ python3 เท่านั้น


2

ใช้งานได้ใน Python 2 และ 3:

>>> import time
>>> import calendar
>>> calendar.timegm(time.gmtime())
1504917998

เพียงติดตามเอกสารอย่างเป็นทางการ ... https://docs.python.org/2/library/time.html#module-time


1) นี่ถือว่าคุณต้องการแปลงตอนนี้ไม่ใช่วัตถุดาต้าไทม์แบบสุ่ม 2) คุณไม่จำเป็นต้องใช้ปฏิทิน time.mktime (randomDateTime.timetuple ()) + randomDateTime.microsecond * 1e-6
Charles Plager

@CharlesPlager time.mktime ไม่ถูกต้อง; มันตีความอาร์กิวเมนต์ในเขตเวลาท้องถิ่นในขณะที่ OP ต้องการเวลาตีความใน UTC (เช่น calendar.timegm ไม่)
stewbasic

นี่เป็นคำตอบที่ถูกต้องที่สุดสำหรับฉันหากคุณกำลังมองหาที่จะแปลงเวลาของคุณใน GMT และคุณต้องการให้มันเป็นอย่างนั้นในการแปลงเป็นเวลาที่ยุค
Yousaf

เพียงทำตามคำตอบของคุณ calendar.timegm (datetime.strptime ("2019-05-03T05: 40: 09.770494 + 00: 00" [: 16], '% Y-% m-% dT% H:% M') timetuple ()) ฉันมีการประทับเวลาใน utc และไม่ว่าระบบใดที่คุณจะใช้งานได้มันทำให้ฉันถูกต้องการประทับเวลาเคล็ดลับคือการใช้ strptime.timetumple
Yousaf

2

สำหรับโซลูชันที่ไม่ขึ้นกับเขตเวลาอย่างชัดเจนให้ใช้ไลบรารี pytz

import datetime
import pytz

pytz.utc.localize(datetime.datetime(2012,4,1,0,0), is_dst=False).timestamp()

เอาท์พุท (ลอย): 1333238400.0


เห็นคำตอบที่คล้ายกันที่stackoverflow.com/a/21145908/4355695แต่อันนี้เป็นหนึ่งซับดีสำหรับกรณีการใช้งานของฉันที่ข้อมูลขาเข้าเป็น UTC และเพียง. timestamp () สันนิษฐานว่าเป็นเวลาท้องถิ่น .
Nikhil VJ

มันใช้งานได้สำหรับวันที่น้อยกว่า 1970 ขอบคุณ คำตอบที่ได้รับการยอมรับไม่ทำงานสำหรับวันที่น้อยกว่า 1970 (Python 3.7.3 64-bit Anaconda3)
canbax

-1

ใน Python 3.7

ส่งคืนวันที่และเวลาที่สอดคล้องกับ date_string ในหนึ่งในรูปแบบที่ปล่อยออกมาโดย date.isoformat () และ datetime.isoformat () ฟังก์ชันนี้รองรับสตริงในรูปแบบ YYYY-MM-DD [* HH [: MM [: SS [.fff [fff]]]] [+ HH: MM [: SS [.ffffff]]] ที่ * สามารถจับคู่อักขระเดี่ยวใดก็ได้

https://docs.python.org/3/library/datetime.html#datetime.datetime.fromisoformat


1
ระวังว่าสิ่งนี้ถูกนำมาใช้ใน Python 3.7
keithpjolley
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.