381 Stimmen

Konvertierung von datetime.date in UTC-Zeitstempel in Python

Ich befasse mich mit Daten in Python und ich brauche, um sie in UTC-Zeitstempel zu konvertieren, verwendet werden in Javascript zu verwenden. Der folgende Code funktioniert nicht:

>>> d = datetime.date(2011,01,01)
>>> datetime.datetime.utcfromtimestamp(time.mktime(d.timetuple()))
datetime.datetime(2010, 12, 31, 23, 0)

Auch die Konvertierung des Datumsobjekts in datetime hilft nicht. Ich habe das Beispiel unter diesem Link ausprobiert Link aus, sondern:

from pytz import utc, timezone
from datetime import datetime
from time import mktime
input_date = datetime(year=2011, month=1, day=15)

und jetzt entweder:

mktime(utc.localize(input_date).utctimetuple())

o

mktime(timezone('US/Eastern').localize(input_date).utctimetuple())

funktioniert.

Also allgemeine Frage: wie kann ich ein Datum in Sekunden seit der Epoche nach UTC umrechnen lassen?

546voto

jfs Punkte 370717

Si d = date(2011, 1, 1) ist in UTC:

>>> from datetime import datetime, date
>>> import calendar
>>> timestamp1 = calendar.timegm(d.timetuple())
>>> datetime.utcfromtimestamp(timestamp1)
datetime.datetime(2011, 1, 1, 0, 0)

Si d ist in der lokalen Zeitzone:

>>> import time
>>> timestamp2 = time.mktime(d.timetuple()) # DO NOT USE IT WITH UTC DATE
>>> datetime.fromtimestamp(timestamp2)
datetime.datetime(2011, 1, 1, 0, 0)

timestamp1 y timestamp2 kann abweichen, wenn Mitternacht in der lokalen Zeitzone nicht dieselbe Zeitinstanz ist wie Mitternacht in UTC.

mktime() kann ein falsches Ergebnis liefern, wenn d entspricht einem Mehrdeutige Ortszeit (z. B. während der Sommerzeitumstellung) oder wenn d ist ein vergangenes (zukünftiges) Datum, an dem der UTC-Offset anders gewesen sein könnte y das C mktime() hat keinen Zugang zu die tz-Datenbank auf der gegebenen Plattform. Sie könnten verwenden. pytz Modul (z. B. über tzlocal.get_localzone() ), um Zugang zur tz-Datenbank auf allen Plattformen zu erhalten . Auch, utcfromtimestamp() kann ausfallen und mktime() kann einen Nicht-POSIX-Zeitstempel zurückgeben, wenn "right" Zeitzone verwendet wird .


Umrechnen datetime.date Objekt, das das Datum in UTC ohne calendar.timegm() :

DAY = 24*60*60 # POSIX day in seconds (exact value)
timestamp = (utc_date.toordinal() - date(1970, 1, 1).toordinal()) * DAY
timestamp = (utc_date - date(1970, 1, 1)).days * DAY

Wie kann ich ein Datum in Sekunden seit Epoche nach UTC umrechnen lassen?

Umrechnen datetime.datetime (nicht datetime.date ) Objekt, das bereits die Zeit in UTC darstellt, mit dem entsprechenden POSIX-Zeitstempel (a float ).

Python 3.3+

datetime.timestamp() :

from datetime import timezone

timestamp = dt.replace(tzinfo=timezone.utc).timestamp()

Hinweis: Es ist erforderlich, die timezone.utc ausdrücklich anders .timestamp() davon ausgehen, dass Ihr naives datetime-Objekt in der lokalen Zeitzone liegt.

Python 3 (< 3.3)

Aus den Dokumentationen für datetime.utcfromtimestamp() :

Es gibt keine Methode, um den Zeitstempel zu erhalten aber der POSIX-Zeitstempel, der einer datetime-Instanz dt entspricht, kann leicht wie folgt berechnet werden. Für ein naives dt:

timestamp = (dt - datetime(1970, 1, 1)) / timedelta(seconds=1)

Und für einen bewussten dt:

timestamp = (dt - datetime(1970,1,1, tzinfo=timezone.utc)) / timedelta(seconds=1)

Interessante Lektüre: Epochenzeit vs. Tageszeit über den Unterschied zwischen Wie spät ist es? y Wie viele Sekunden sind verstrichen?

Siehe auch: datetime braucht eine "Epoche"-Methode

Python 2

Zur Anpassung des obigen Codes für Python 2:

timestamp = (dt - datetime(1970, 1, 1)).total_seconds()

donde timedelta.total_seconds() ist gleichbedeutend mit (td.microseconds + (td.seconds + td.days * 24 * 3600) * 10**6) / 10**6 mit aktivierter echter Division berechnet.

Ejemplo

from __future__ import division
from datetime import datetime, timedelta

def totimestamp(dt, epoch=datetime(1970,1,1)):
    td = dt - epoch
    # return td.total_seconds()
    return (td.microseconds + (td.seconds + td.days * 86400) * 10**6) / 10**6 

now = datetime.utcnow()
print now
print totimestamp(now)

Vorsicht vor Gleitkomma-Probleme .

Salida

2012-01-08 15:34:10.022403
1326036850.02

Wie konvertiert man eine bewusste datetime Objekt in POSIX-Zeitstempel

assert dt.tzinfo is not None and dt.utcoffset() is not None
timestamp = dt.timestamp() # Python 3.3+

Zu Python 3:

from datetime import datetime, timedelta, timezone

epoch = datetime(1970, 1, 1, tzinfo=timezone.utc)
timestamp = (dt - epoch) / timedelta(seconds=1)
integer_timestamp = (dt - epoch) // timedelta(seconds=1)

Zu Python 2:

# utc time = local time              - utc offset
utc_naive  = dt.replace(tzinfo=None) - dt.utcoffset()
timestamp = (utc_naive - datetime(1970, 1, 1)).total_seconds()

113voto

Ulf Aslak Punkte 6808

Para nur Unix-Systeme :

>>> import datetime
>>> d = datetime.date(2011, 1, 1)
>>> d.strftime("%s")  # <-- THIS IS THE CODE YOU WANT
'1293832800'

Anmerkung 1: dizzyf stellte fest, dass dies wendet lokalisierte Zeitzonen an . Nicht für die Produktion verwenden.

Anmerkung 2: Jakub Narebski stellte fest, dass dies ignoriert Zeitzoneninformationen auch für offset-aware datetime (getestet für Python 2.7).

44voto

DRH Punkte 7608
  • Annahme 1: Sie versuchen, ein Datum in einen Zeitstempel zu konvertieren. Da ein Datum jedoch einen Zeitraum von 24 Stunden abdeckt, gibt es keinen einzigen Zeitstempel, der dieses Datum repräsentiert. Ich gehe davon aus, dass Sie den Zeitstempel dieses Datums um Mitternacht (00:00:00.000) darstellen wollen.

  • Annahme 2: Das von Ihnen angegebene Datum ist nicht mit einer bestimmten Zeitzone verbunden, Sie möchten jedoch den Abstand zu einer bestimmten Zeitzone (UTC) bestimmen. Ohne die Zeitzone zu kennen, in der das Datum liegt, ist es nicht möglich, einen Zeitstempel für eine bestimmte Zeitzone zu berechnen. Ich gehe davon aus, dass Sie das Datum so behandeln wollen, als befände es sich in der lokalen Systemzeitzone.

Zunächst können Sie die Datumsinstanz in ein Tupel umwandeln, das die verschiedenen Zeitkomponenten darstellt, indem Sie die timetuple() Mitglied:

dtt = d.timetuple() # time.struct_time(tm_year=2011, tm_mon=1, tm_mday=1, tm_hour=0, tm_min=0, tm_sec=0, tm_wday=5, tm_yday=1, tm_isdst=-1)

Sie können dies dann in einen Zeitstempel umwandeln mit time.mktime :

ts = time.mktime(dtt) # 1293868800.0

Sie können diese Methode überprüfen, indem Sie sie mit der Epochenzeit selbst (1970-01-01) testen. In diesem Fall sollte die Funktion den Zeitzonen-Offset für die lokale Zeitzone an diesem Datum zurückgeben:

d = datetime.date(1970,1,1)
dtt = d.timetuple() # time.struct_time(tm_year=1970, tm_mon=1, tm_mday=1, tm_hour=0, tm_min=0, tm_sec=0, tm_wday=3, tm_yday=1, tm_isdst=-1)
ts = time.mktime(dtt) # 28800.0

28800.0 ist 8 Stunden, was für die pazifische Zeitzone (in der ich mich befinde) korrekt wäre.

10voto

agittarius Punkte 569

Ich habe meine eigenen zwei Funktionen definiert

  • utc_time2datetime(utc_time, tz=None)
  • datetime2utc_time(datetime)

hier:

import time
import datetime
from pytz import timezone
import calendar
import pytz

def utc_time2datetime(utc_time, tz=None):
    # convert utc time to utc datetime
    utc_datetime = datetime.datetime.fromtimestamp(utc_time)

    # add time zone to utc datetime
    if tz is None:
        tz_datetime = utc_datetime.astimezone(timezone('utc'))
    else:
        tz_datetime = utc_datetime.astimezone(tz)

    return tz_datetime

def datetime2utc_time(datetime):
    # add utc time zone if no time zone is set
    if datetime.tzinfo is None:
        datetime = datetime.replace(tzinfo=timezone('utc'))

    # convert to utc time zone from whatever time zone the datetime is set to
    utc_datetime = datetime.astimezone(timezone('utc')).replace(tzinfo=None)

    # create a time tuple from datetime
    utc_timetuple = utc_datetime.timetuple()

    # create a time element from the tuple an add microseconds
    utc_time = calendar.timegm(utc_timetuple) + datetime.microsecond / 1E6

    return utc_time

8voto

Wang Punkte 6069

Folgen Sie dem Python2.7-Dokument, Sie müssen calendar.timegm() anstelle von time.mktime() verwenden

>>> d = datetime.date(2011,01,01)
>>> datetime.datetime.utcfromtimestamp(calendar.timegm(d.timetuple()))
datetime.datetime(2011, 1, 1, 0, 0)

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X