Python Erstellen Sie in fünf Minuten einen Unix-Zeitstempel

297

Ich muss in 5 Minuten einen "Expires" -Wert erstellen, muss ihn jedoch im UNIX-Zeitstempelformat angeben. Ich habe das bisher, aber es scheint wie ein Hack.

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

Gibt es ein Modul oder eine Funktion, die die Zeitstempelkonvertierung für mich durchführt?

Daniel Rhoden
quelle
7
Ich empfehle, das Thema dieser Frage zu wechseln. Die Frage ist gut, aber es geht nicht darum, datetime in Unix-Zeitstempel zu konvertieren. Es geht darum, wie Sie in 5 Minuten einen Unix-Zeitstempel erhalten.
DA
Ich bin anderer Meinung, @DA Die Frage lautet im Wesentlichen: "Ich muss X und Y machen. Hier ist, was ich jetzt habe. Was ist ein besserer Weg, um Y zu machen?" Vielleicht gibt es bessere Möglichkeiten, X zu machen, aber der Titel und der Körper fragen eindeutig nach Y.
Rob Kennedy
6
Ich stimme Ihnen in dieser Frage voll und ganz zu, und ich denke, es ist eine gute Frage mit einer guten Antwort. Das Problem ist, dass "Python datetime to Unix timestamp" weder die Frage noch die Antwort widerspiegelt. Ich fand diesen Beitrag auf der Suche nach einer Möglichkeit, die Konvertierung durchzuführen, und verlor Zeit aufgrund der irreführenden Betreffzeile. Ich schlage vor: "Python, 5 Minuten in der Zukunft als UNIX-Zeitstempel"
DA
3
@ JimmyKane - Eine ziemlich umfassende Antwort, wie man einen Zeitstempel von einer Datumszeit erhält, finden Sie hier: stackoverflow.com/questions/8777753/…
Tim Tisdall
@ TimTisdall ja, da der Titel geändert wird, macht es keinen Sinn
Jimmy Kane

Antworten:

349

Ein anderer Weg ist zu verwenden calendar.timegm:

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

Es ist auch portabler als %sFlag to strftime(was unter Windows nicht funktioniert).

Cat Plus Plus
quelle
Danke D.Shawley. help (datetime.timedelta) hat diese Verknüpfung nicht erwähnt. Es hatte nur Tage, Sekunden und Mikrosekunden.
Daniel Rhoden
12
Beachten Sie, dass die richtige Lösung in Kombination der beiden vorherigen Kommentare lautet : calendar.timegm(future.utctimetuple()). Dies stellt sicher, dass eine UTC-Zeit übergeben wird calendar.timegm.
Schattenmaterie
1
Ich kann den Kommentar von @ tumbleweed nicht genug bewerten. Wenn Sie versuchen, einen UNIX-Zeitstempel (und damit einen in UTC) abzurufen, verwenden Sie calendar.timegm.
Bialecki
@tumbleweed, richtig. Wenn Sie mktime plus gmtime (0) verwenden, wird für jede Zeitzone außer UTC ein Roundtrip-Delta ungleich Null angezeigt: z. B. `time.mktime (datetime.fromtimestamp (time.mktime (time.gmtime (0))). Timetuple ())` gibt 21600.0Sekunden (6 Stunden) statt 0.0 für die TZ
Kochfelder
Wenn Sie einen UTC-Zeitstempel erhalten möchten, sollten Sie Folgendes verwenden : calendar.timegm(datetime.datetime.utcnow().timetuple()). Die Verwendung der Methode datetime.datetime.now().utctimetuple()funktioniert bei mir nicht (Python 3.2).
Wookie88
155

Jetzt können Sie in Python> = 3.3 einfach die timestamp () -Methode aufrufen , um den Zeitstempel als Float abzurufen.

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
Tim Tisdall
quelle
4
+1 dafür. Es sollte viel höher angezeigt werden, weil es die saubere Art ist, wie man das in Python 3 macht
Viktor Stískala
2
@ scott654 Ich dachte, es gleich am Anfang des Kommentars zu haben, machte es klar genug, aber ich fügte auch etwas Fett hinzu.
Tim Tisdall
1
Ich würde die Notiz als Kommentar im Codeblock machen, weil wir alle nur zuerst den Code in den Antworten scannen und den Rest nur lesen, wenn der Code gut aussieht. Gute Antwort.
Matthew Purdon
2
Ortszeit kann mehrdeutig sein . Das Beispiel ( datetime.now()) ist schlecht, da es die Verwendung von naiven Datetime-Objekten fördert, die die Ortszeit darstellen, und bei DST-Übergängen (aufgrund der inhärenten Mehrdeutigkeit) möglicherweise fehlschlägt. Sie könnten ts = datetime.now(timezone.utc).timestamp()stattdessen verwenden.
JFS
@ JFSebastian - guter Punkt. Ich wollte die Importe jedoch nicht ergänzen, also habe ich sie geändert utcnow(). Ich bin es gewohnt, auf Computern zu arbeiten, auf denen die Zeitzone auf UTC eingestellt ist, aber das sollte in diesem Codeausschnitt nicht angenommen werden.
Tim Tisdall
139

Ich habe das gerade gefunden und es ist noch kürzer.

import time
def expires():
    '''return a UNIX style timestamp representing 5 minutes from now'''
    return int(time.time()+300)
Daniel Rhoden
quelle
12
Dies beantwortet die Frage nicht.
Jesse Dhillon
22
@ JesseDhillon beantwortet die Frage (machen Sie einen UNIX-Zeitstempel 5 Minuten in der Zukunft), nur nicht den Titel.
dbr
3
time.time()kann zurückgesetzt werden. Um 5 Minuten in der Zukunft einen "Expires" -Wert zu erstellen, benötigen Sie time.monotonic()je nach Anwendungsfall möglicherweise Analog.
JFS
@ jf-sebastian time.monotonic () gibt keinen UNIX-Zeitstempel zurück, sondern einen Zeitstempel mit einem undefinierten Referenzpunkt.
rspeer
@rspeer: Ja, wie die Dokumente sagen , ist nur der Unterschied zwischen aufeinanderfolgenden Aufrufen gültig. Ob monotonicverwendet werden kann, hängt von Ihrem Anwendungsfall ab, z. B. verwendet das subprocessModul diese timeoutOption , um die Option zu implementieren .
JFS
57

Das brauchen Sie:

import time
import datetime
n = datetime.datetime.now()
unix_time = time.mktime(n.timetuple())
Ali
quelle
Wie unterscheidet sich das oder ergänzt es um das bereitgestellte "Cat Plus Plus"?
David
3
Dies ist beispielsweise die Antwort auf die Frage "Python-Datums- und Unix-Zeitstempel", während Cat Plus Plus die Frage "Python-Datumszeit für Unix-Zeitstempel in 5 Minuten" beantwortet. Dieser ist also sauber und offensichtlich.
running.t
@ running.t: es erinnert mich: "Jedes Problem hat eine einfache, offensichtliche und falsche Lösung". Siehe mögliche Probleme mitmktime(dt.timetuple()) . datetime.now(timezone.utc).timestamp()bereitgestellt von @Tim Tisdall ist die Lösung in Python 3.3+. Andernfalls (dt - epoch).total_seconds()könnte verwendet werden .
JFS
@JFSebastian Was ist, wenn ich wirklich möchte, dass alle Berechnungen in der Ortszeit stattfinden? Ist es der Fall, wenn z. Eine naive Zeichenfolge zu analysieren, von der man weiß, dass sie Ortszeit ist, und zu entscheiden, ob in dieser bestimmten Zeit eine Sommerzeit wirksam war?
n611x007
1
@naxa: ja, einige Ortszeiten sind mehrdeutig oder nicht vorhanden. Auch der Zeitzonenversatz kann aus anderen Gründen als der Sommerzeit unterschiedlich sein (Sie benötigen eine tz-Datenbank wie pytz, um den richtigen Versatz herauszufinden). Ortszeit bedeutet, dass alles, was der Lokalpolitiker für eine gute Idee hält, um die Zeit zu messen, dh sehr unregelmäßig sein kann.
JFS
48

Sie können verwenden datetime.strftime, um die Zeit in Epochenform mithilfe der %sFormatzeichenfolge abzurufen:

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

Hinweis: Dies funktioniert nur unter Linux und diese Methode funktioniert nicht mit Zeitzonen.

Mipadi
quelle
32
Dies ist ein etwas undokumentiertes Verhalten ( python.org/doc/current/library/datetime.html ). Scheint unter Linux zu arbeiten und nicht unter Win32 (Generieren ValueError: Invalid format string).
Antony Hatchkins
3
Diese Methode funktioniert nicht mit Zeitzonen. Wenn Sie die Zeitzone ändern, erhalten Sie das gleiche Ergebnis datetime (2013, 12, 7, tzinfo = Zeitzone ("Amerika / Chicago")). Strftime ("% s") 1386385200 datetime (2013, 12, 7, tzinfo = timezone ("Europe /") Riga ")). Strftime ("% s ") 1386385200
Martins Balodis
11

Hier ist eine weniger kaputte datetimeLösung zum Konvertieren vom Datum / Uhrzeit-Objekt in den Posix-Zeitstempel:

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

Weitere Informationen finden Sie unter Konvertieren von datetime.date in UTC-Zeitstempel in Python .

jfs
quelle
6
def in_unix(input):
  start = datetime.datetime(year=1970,month=1,day=1)
  diff = input - start
  return diff.total_seconds()
Sravan
quelle
4

Der Schlüssel besteht darin, sicherzustellen, dass alle von Ihnen verwendeten Daten in der utc-Zeitzone liegen, bevor Sie mit der Konvertierung beginnen. Unter http://pytz.sourceforge.net/ erfahren Sie, wie Sie dies richtig machen. Durch die Normalisierung auf utc beseitigen Sie die Mehrdeutigkeit von Sommerzeitübergängen. Dann können Sie timedelta sicher verwenden, um die Entfernung von der Unix-Epoche zu berechnen und dann in Sekunden oder Millisekunden umzuwandeln.

Beachten Sie, dass sich der resultierende Unix-Zeitstempel selbst in der UTC-Zeitzone befindet. Wenn Sie den Zeitstempel in einer lokalisierten Zeitzone anzeigen möchten, müssen Sie eine weitere Konvertierung durchführen.

Beachten Sie auch, dass dies nur für Daten nach 1970 funktioniert.

   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
fawce
quelle
3
Hinweis: Ich verstehe "den [Unix] -Zeitstempel in einer lokalisierten Zeitzone" nicht. Der Zeitstempel ist der gleiche (seitdem verstrichene Sekunden 1970-01-01 00:00:00+00:00). So erhalten Sie ein naives datetime-Objekt in der lokalen Zeitzone:datetime.fromtimestamp(ts)
jfs
4

Das Folgende basiert auf den obigen Antworten (plus einer Korrektur für die Millisekunden) und emuliert datetime.timestamp()für Python 3 vor 3.3, wenn Zeitzonen verwendet werden.

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

Um die gestellte Frage genau zu beantworten, möchten Sie:

datetime_timestamp(my_datetime) + 5 * 60

datetime_timestampist Teil von simple-date . Aber wenn Sie dieses Paket verwenden würden, würden Sie wahrscheinlich Folgendes eingeben:

SimpleDate(my_datetime).timestamp + 5 * 60

Hier werden viele weitere Formate / Typen für my_datetime verarbeitet.

Andrew Cooke
quelle
sollten Sie nicht (5 * 60) hinzufügen, um 5 Minuten hinzuzufügen? Ich denke, nur das Hinzufügen von 5 fügt dem Zeitstempel nur 5 Sekunden hinzu.
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
hd1
quelle
1

Beachten Sie, dass Lösungen mit timedelta.total_seconds()Python-2.7 + funktionieren. Verwenden Sie calendar.timegm(future.utctimetuple())für niedrigere Versionen von Python.

mighq
quelle