Python สร้างการประทับเวลา unix ห้านาทีในอนาคต


297

ฉันต้องสร้างค่า "หมดอายุ" ในอนาคต 5 นาที แต่ฉันต้องจัดหาในรูปแบบ UNIX Timestamp ฉันมีจนถึงตอนนี้ แต่ดูเหมือนแฮ็ค

def expires():
    '''return a UNIX style timestamp representing 5 minutes from now'''
    epoch = datetime.datetime(1970, 1, 1)
    seconds_in_a_day = 60 * 60 * 24
    five_minutes = datetime.timedelta(seconds=5*60)
    five_minutes_from_now = datetime.datetime.now() + five_minutes
    since_epoch = five_minutes_from_now - epoch
    return since_epoch.days * seconds_in_a_day + since_epoch.seconds

มีโมดูลหรือฟังก์ชั่นที่ทำการแปลงเวลาสำหรับฉันหรือไม่?


7
ฉันแนะนำให้เปลี่ยนหัวข้อของคำถามนี้ คำถามนั้นดี แต่ไม่เกี่ยวกับการแปลงวันที่และเวลาเป็น Unix timestamp มันเป็นเรื่องเกี่ยวกับวิธีที่จะได้รับการประทับเวลา Unix 5 นาทีในอนาคต
DA

ฉันไม่เห็นด้วย @DA คำถามหลักบอกว่า "ฉันต้องทำ X และ Y นี่คือสิ่งที่ฉันมีตอนนี้วิธีที่ดีกว่าในการทำ Y คืออะไร" อาจจะมีวิธีที่ดีกว่าในการทำ X แต่ชื่อและร่างกายจะถามเกี่ยวกับ Y อย่างชัดเจน
Rob Kennedy

6
ฉันเห็นด้วยกับคุณอย่างสมบูรณ์เกี่ยวกับคำถามและฉันคิดว่ามันเป็นสิ่งที่ดีกับคำตอบที่ดี ปัญหาคือ "Python datetime เป็น Unix timestamp" ไม่ได้สะท้อนคำถามหรือคำตอบ ฉันพบโพสต์นี้กำลังค้นหาวิธีในการทำ Conversion และฉันเสียเวลาเนื่องจากหัวเรื่องที่ทำให้เข้าใจผิด ฉันขอแนะนำ: "Python 5 นาทีในอนาคตเป็น UNIX Timestamp"
DA

3
@JimmyKane - คำตอบที่ครอบคลุมเกี่ยวกับวิธีการรับประทับเวลาจากวันที่สามารถพบได้ที่นี่: stackoverflow.com/questions/8777753/ …
Tim Tisdall

@TimTisdall ใช่ตั้งแต่เปลี่ยนชื่อแล้วมันก็ไม่สมเหตุสมผล
Jimmy Kane

คำตอบ:


349

อีกวิธีหนึ่งคือการใช้calendar.timegm:

future = datetime.datetime.utcnow() + datetime.timedelta(minutes=5)
return calendar.timegm(future.timetuple())

นอกจากนี้ยังพกพาได้มากกว่าการ%sตั้งค่าสถานะเป็นstrftime(ซึ่งไม่ทำงานบน Windows)


ขอบคุณ D.Shawley ความช่วยเหลือ (datetime.timedelta) ไม่ได้กล่าวถึงทางลัดนั้น มีเพียงวันวินาทีและไมโครวินาทีเท่านั้น
Daniel Rhoden

12
calendar.timegm(future.utctimetuple())โปรดทราบว่าการรวมก่อนหน้านี้สองความเห็นทางออกที่เหมาะสมคือ เพื่อให้แน่ใจว่านี้เป็นเวลา UTC calendar.timegmจะผ่านเข้าสู่
shadowmatter

1
ไม่สามารถโหวตความคิดเห็นของ @ tumbleweed ได้มากพอ หากคุณกำลังพยายามที่จะได้รับการประทับเวลา UNIX (และหนึ่งใน UTC) ให้ใช้ calendar.timegm
Bialecki

@ tumbleweed ใช่มั้ย หากคุณใช้ mktime บวก gmtime (0) จะทำให้เดลต้าไปกลับสำหรับเขตเวลาใดก็ได้นอกเหนือจาก UTC: เช่น `time.mktime (datetime.fromtimestamp (time.mktime (time.gmtime (0))) scheduple ()) ให้21600.0วินาที (6 ชั่วโมง) แทน 0.0 สำหรับ TZ ของเครื่องยูนิกซ์
hobs

หากคุณต้องการที่จะได้รับการประทับเวลา UTC calendar.timegm(datetime.datetime.utcnow().timetuple())คุณควรใช้นี้ วิธีการใช้datetime.datetime.now().utctimetuple()ไม่ได้ผลสำหรับฉัน (Python 3.2)
Wookie88

155

ตอนนี้ใน Python> = 3.3คุณสามารถเรียกเมธอดการประทับเวลา ()เพื่อรับการประทับเวลาแบบลอย

import datetime
current_time = datetime.datetime.now(datetime.timezone.utc)
unix_timestamp = current_time.timestamp() # works if Python >= 3.3

unix_timestamp_plus_5_min = unix_timestamp + (5 * 60)  # 5 min * 60 seconds

4
+1 สำหรับสิ่งนี้ มันควรจะแสดงให้สูงขึ้นมากเพราะมันเป็นวิธีที่สะอาดใน Python 3
Viktor Stískala

2
@ scott654 ฉันคิดว่าการที่ถูกต้องในตอนต้นของความคิดเห็นทำให้มันชัดเจนเพียงพอ แต่ฉันก็เพิ่มความกล้าลงไปด้วย
Tim Tisdall

1
ฉันจะทำบันทึกเป็นความคิดเห็นในบล็อกรหัสเพราะเราทุกคนแค่สแกนรหัสในคำตอบก่อนและอ่านส่วนที่เหลือถ้ารหัสดูดี คำตอบที่ดีแม้ว่า
Matthew Purdon

2
เวลาท้องถิ่นอาจจะ ambigous ตัวอย่าง ( datetime.now()) ไม่ถูกต้องเนื่องจากมันสนับสนุนการใช้วัตถุไร้เดียงสา datetime ที่แสดงเวลาท้องถิ่นและอาจล้มเหลวในระหว่างการเปลี่ยน DST (เนื่องจากความกำกวมโดยธรรมชาติ) คุณสามารถใช้ts = datetime.now(timezone.utc).timestamp()แทน
jfs

@JFSebastian - จุดดี utcnow()ผมไม่ได้ต้องการที่จะเพิ่มการนำเข้าแม้ว่าดังนั้นฉันเปลี่ยนไป ฉันคุ้นเคยกับการทำงานกับเครื่องที่ตั้งค่าเขตเวลาเป็น UTC แต่ไม่ควรสันนิษฐานว่าในข้อมูลโค้ดนี้
Tim Tisdall

139

เพิ่งพบสิ่งนี้และมันก็สั้นกว่า

import time
def expires():
    '''return a UNIX style timestamp representing 5 minutes from now'''
    return int(time.time()+300)

12
สิ่งนี้ไม่ตอบคำถาม
Jesse Dhillon

22
@JesseDhillon ตอบคำถาม (ทำ UNIX Timestamp 5 นาทีในอนาคต) ไม่ใช่แค่ชื่อ
dbr

3
time.time()สามารถตั้งค่ากลับมา ในการสร้างมูลค่า "หมดอายุ" 5 นาทีในอนาคตคุณอาจต้องใช้ time.monotonic()อะนาล็อกขึ้นอยู่กับการใช้งานของคุณ
jfs

@ jf-sebastian time.monotonic () ไม่ส่งคืนการประทับเวลา UNIX มันจะส่งคืนการประทับเวลาด้วยจุดอ้างอิงที่ไม่ได้กำหนด
rspeer

@rspeer: ใช่อย่างที่เอกสารบอกว่ามีความแตกต่างระหว่างการโทรติดต่อกันเท่านั้นที่ถูกต้อง monotonicสามารถใช้งานได้หรือไม่นั้นขึ้นอยู่กับการใช้งานของคุณตัวอย่างเช่นsubprocessโมดูลจะใช้เพื่อนำไปใช้กับtimeoutตัวเลือก
jfs

57

นี่คือสิ่งที่คุณต้องการ:

import time
import datetime
n = datetime.datetime.now()
unix_time = time.mktime(n.timetuple())

สิ่งนี้แตกต่างหรือเพิ่มให้กับ 'Cat Plus Plus' ที่ให้ไว้อย่างไร
เดวิด

3
EG นี่คือคำตอบสำหรับคำถาม "Python datetime ไปยัง Unix timestamp" ในขณะที่ Cat Plus Plus ตอบคำถาม "Python datetime ที่จะอยู่ใน 5 นาทีถึง Unix timestamp" ดังนั้นอันนี้สะอาดและชัดเจน
running.t

@ running.t: มันทำให้ฉันนึกถึง: "ทุกปัญหามีวิธีที่ง่ายชัดเจนและผิด " ดูปัญหาไปได้ด้วย mktime(dt.timetuple())datetime.now(timezone.utc).timestamp()จัดหาให้โดย @Tim Tisdall เป็นทางออกใน Python 3.3+ มิฉะนั้นอาจถูกนำมาใช้(dt - epoch).total_seconds()
jfs

@JFSebastian จะเป็นอย่างไรถ้าฉันต้องการให้การคำนวณทั้งหมดเกิดขึ้นในเวลาท้องถิ่น มันเป็นกรณีเมื่อเช่น การแยกสตริงที่ไร้เดียงสาที่เรารู้ว่าเป็น localtime และตัดสินใจว่าจะมี DST ที่มีผลบังคับใช้ในเวลานั้นหรือไม่
n611x007

1
@naxa: ใช่เวลาท้องถิ่นบางอย่างไม่ชัดเจนหรือไม่มีอยู่จริง นอกจากนี้เขตเวลาชดเชยอาจแตกต่างกันด้วยเหตุผลอื่นที่ไม่ใช่ DST (คุณต้องการฐานข้อมูล tz เช่น pytz เพื่อหาค่าออฟเซ็ตที่ถูกต้อง) เวลาท้องถิ่นหมายถึงสิ่งที่นักการเมืองท้องถิ่นคิดว่าเป็นความคิดที่ดีในการวัดเวลา Ie มันอาจผิดปกติอย่างมาก
jfs

48

คุณสามารถใช้datetime.strftimeเพื่อให้ได้เวลาในรูปแบบของยุคโดยใช้%sรูปแบบสตริง:

def expires():
    future = datetime.datetime.now() + datetime.timedelta(seconds=5*60)
    return int(future.strftime("%s"))

หมายเหตุ: ใช้งานได้กับ linux เท่านั้นและวิธีนี้ใช้ไม่ได้กับเขตเวลา


32
นี่เป็นพฤติกรรมที่ค่อนข้างไม่มีเอกสาร ( python.org/doc/current/library/datetime.html ) ดูเหมือนว่าจะทำงานภายใต้ linux และไม่ทำงานภายใต้ win32 (สร้างValueError: Invalid format string)
Antony Hatchkins

3
วิธีนี้ใช้ไม่ได้กับเขตเวลา การเปลี่ยนเขตเวลาจะให้ผลลัพธ์ที่เหมือนกัน (2013,12,7, tzinfo = เขตเวลา ("อเมริกา / ชิคาโก")) strftime ("% s") 1386385200 datetime (2013,12,7, tzinfo = เขตเวลา ("ยุโรป / ริกา ")). strftime ("% s ") 1386385200
Martins Balodis

11

ต่อไปนี้เป็นdatetimeโซลูชันที่ใช้หักน้อยกว่าในการแปลงจากวัตถุ datetime เป็น posix timestamp:

future = datetime.datetime.utcnow() + datetime.timedelta(minutes=5)
return (future - datetime.datetime(1970, 1, 1)).total_seconds()

ดูรายละเอียดเพิ่มเติมได้ที่แปลง datetime.date กับ UTC ประทับเวลาในหลาม



4

กุญแจสำคัญคือเพื่อให้แน่ใจว่าวันที่ทั้งหมดที่คุณใช้อยู่ในเขตเวลา utc ก่อนที่จะเริ่มการแปลง ดูhttp://pytz.sourceforge.net/เพื่อเรียนรู้วิธีการทำอย่างถูกต้อง ด้วยการทำให้เป็นปกติคุณจะกำจัดความคลุมเครือของการเปลี่ยนการประหยัดเวลากลางวัน จากนั้นคุณสามารถใช้ timedelta อย่างปลอดภัยเพื่อคำนวณระยะทางจากยูนิกซ์ยุคแล้วแปลงเป็นวินาทีหรือมิลลิวินาที

โปรดทราบว่าการประทับเวลา unix ที่เกิดขึ้นนั้นอยู่ในเขตเวลา UTC หากคุณต้องการดูการประทับเวลาในเขตเวลาท้องถิ่นคุณจะต้องทำการแปลงอีกครั้ง

นอกจากนี้โปรดทราบว่าจะใช้งานได้สำหรับวันที่หลังปี 1970 เท่านั้น

   import datetime
   import pytz

   UNIX_EPOCH = datetime.datetime(1970, 1, 1, 0, 0, tzinfo = pytz.utc)
   def EPOCH(utc_datetime):
      delta = utc_datetime - UNIX_EPOCH
      seconds = delta.total_seconds()
      ms = seconds * 1000
      return ms

3
หมายเหตุ: ฉันไม่เข้าใจ "การประทับเวลา [unix] ในเขตเวลาที่แปลแล้ว" การประทับเวลาเหมือนกัน (นับตั้งแต่วินาทีที่ผ่านไป1970-01-01 00:00:00+00:00) เพื่อรับวัตถุ datetime ไร้เดียงสาในเขตเวลาท้องถิ่น:datetime.fromtimestamp(ts)
jfs

4

ต่อไปนี้เป็นไปตามคำตอบข้างต้น (บวกการแก้ไขสำหรับมิลลิวินาที) และจำลองdatetime.timestamp()สำหรับ Python 3 ก่อน 3.3 เมื่อใช้เขตเวลา

def datetime_timestamp(datetime):
    '''
    Equivalent to datetime.timestamp() for pre-3.3
    '''
    try:
        return datetime.timestamp()
    except AttributeError:
        utc_datetime = datetime.astimezone(utc)
        return timegm(utc_datetime.timetuple()) + utc_datetime.microsecond / 1e6

หากต้องการตอบคำถามตามที่ขออย่างเคร่งครัดคุณต้องการ:

datetime_timestamp(my_datetime) + 5 * 60

datetime_timestampเป็นส่วนหนึ่งของวันที่ง่าย แต่ถ้าคุณใช้แพ็คเกจนั้นคุณอาจจะพิมพ์:

SimpleDate(my_datetime).timestamp + 5 * 60

ซึ่งจัดการรูปแบบ / ประเภทอื่น ๆ อีกมากมายสำหรับ my_datetime


คุณไม่ควรเพิ่ม (5 * 60) เพื่อเพิ่ม 5 นาที? ฉันคิดว่าเพียงแค่เพิ่ม 5 เพิ่มเพียง 5 วินาทีในการประทับเวลา
Tim Tisdall

1
def expiration_time():
    import datetime,calendar
    timestamp = calendar.timegm(datetime.datetime.now().timetuple())
    returnValue = datetime.timedelta(minutes=5).total_seconds() + timestamp
    return returnValue

1

โปรดทราบว่าโซลูชันที่timedelta.total_seconds()ทำงานกับ python-2.7 + ใช้calendar.timegm(future.utctimetuple())สำหรับ Python เวอร์ชันที่ต่ำกว่า

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