Wie kann ich eine ISO 8601-Datetime-Zeichenfolge in einen Python Datetime-Objekt übersetzen? [Duplikat]
-
13-09-2019 - |
Frage
Diese Frage bereits eine Antwort hier:
- Wie analysiere ich eine ISO 8601-Format Datum? 25 Antworten
Ich erhalte eine Datetime-Zeichenfolge in einem Format wie "2009-05-28T16: 15: 00" (dies ist ISO 8601, glaube ich). Eine hackish Option scheint die Zeichenfolge mit time.strptime
und vorbei an den ersten sechs Elemente des Tupels in den Datetime-Konstruktor zu analysieren zu sein, wie:
datetime.datetime(*time.strptime("2007-03-04T21:08:12", "%Y-%m-%dT%H:%M:%S")[:6])
Ich habe nicht in der Lage gewesen, eine „saubere“ Art und Weise, dies zu tun zu finden. Gibt es eine?
Lösung
Ich ziehe mit der dateutil Bibliothek für Zeitzone Handhabung und im Allgemeinen fest Datum Parsing. Wenn Sie ein ISO-8601-String zu erhalten waren wie: 2010-05-08T23: 41: 54.000Z würden Sie eine schöne Zeit haben Parsen, dass mit strptime, vor allem wenn Sie nicht bis wusste Front, ob die Zeitzone enthalten war. pyiso8601 hat ein paar Probleme (überprüfen ihre Tracker), die ich in meiner während Benutzung lief und es hat sich in wenigen Jahren nicht mehr aktualisiert. dateutil, dagegen aktiv war und arbeitete für mich:
import dateutil.parser
yourdate = dateutil.parser.parse(datestring)
Andere Tipps
Da Python 3.7 und keine externen Bibliotheken:
datetime.datetime.strptime('2019-01-04T16:41:24+0200', "%Y-%m-%dT%H:%M:%S%z")
Python 2 unterstützen nicht die %z
Formatspezifizierer, so ist es am besten explizite Zeit Zulu verwenden überall, wenn möglich:
datetime.datetime.strptime("2007-03-04T21:08:12Z", "%Y-%m-%dT%H:%M:%SZ")
Da ISO 8601 viele Variationen von optionalen Doppelpunkten und Strichen vorhanden ist, im Grunde CCYY-MM-DDThh:mm:ss[Z|(+|-)hh:mm]
erlaubt. Wenn Sie verwenden strptime wollen, müssen Sie zuerst die Variationen Streifen aus.
Das Ziel ist es, ein UTC Datetime-Objekt zu erzeugen.
Wenn Sie nur einen grundlegenden Fall, dass die für die UTC mit dem Z-Suffix wie 2016-06-29T19:36:29.3453Z
arbeiten:
datetime.datetime.strptime(timestamp.translate(None, ':-'), "%Y%m%dT%H%M%S.%fZ")
Wenn Sie Zeitzone Offsets wie 2016-06-29T19:36:29.3453-0400
oder 2008-09-03T20:56:35.450686+05:00
behandeln möchten die folgende verwenden. Diese werden konvertiert alle Variationen in etwas ohne variable Trennzeichen wie 20080903T205635.450686+0500
macht es konsequenter / leichter zu analysieren.
import re
# This regex removes all colons and all
# dashes EXCEPT for the dash indicating + or - utc offset for the timezone
conformed_timestamp = re.sub(r"[:]|([-](?!((\d{2}[:]\d{2})|(\d{4}))$))", '', timestamp)
datetime.datetime.strptime(conformed_timestamp, "%Y%m%dT%H%M%S.%f%z" )
Wenn Sie Ihr System nicht die %z
strptime Richtlinie nicht unterstützt (Sie so etwas wie ValueError: 'z' is a bad directive in format '%Y%m%dT%H%M%S.%f%z'
sehen), dann müssen Sie manuell die Zeit von Z
(UTC) kompensieren. Hinweis %z
kann auf Ihrem System in Python-Versionen nicht funktionieren <3, wie es auf der C-Bibliothek Unterstützung angewiesen, die über System / Python Buildtyp variiert (dh Jython , Cython usw.).
import re
import datetime
# This regex removes all colons and all
# dashes EXCEPT for the dash indicating + or - utc offset for the timezone
conformed_timestamp = re.sub(r"[:]|([-](?!((\d{2}[:]\d{2})|(\d{4}))$))", '', timestamp)
# Split on the offset to remove it. Use a capture group to keep the delimiter
split_timestamp = re.split(r"[+|-]",conformed_timestamp)
main_timestamp = split_timestamp[0]
if len(split_timestamp) == 3:
sign = split_timestamp[1]
offset = split_timestamp[2]
else:
sign = None
offset = None
# Generate the datetime object without the offset at UTC time
output_datetime = datetime.datetime.strptime(main_timestamp +"Z", "%Y%m%dT%H%M%S.%fZ" )
if offset:
# Create timedelta based on offset
offset_delta = datetime.timedelta(hours=int(sign+offset[:-2]), minutes=int(sign+offset[-2:]))
# Offset datetime with timedelta
output_datetime = output_datetime + offset_delta
Pfeil sieht vielversprechend für diese:
>>> import arrow
>>> arrow.get('2014-11-13T14:53:18.694072+00:00').datetime
datetime.datetime(2014, 11, 13, 14, 53, 18, 694072, tzinfo=tzoffset(None, 0))
Pfeil ist eine Python-Bibliothek, die von der Erstellung, Bearbeitung, Formatierung und Umwandeln Daten und Zeiten eine sensible, intelligente Weise bereitstellt. Pfeil ist einfach, leicht und stark inspiriert von moment.js und fordert .
Sie sollten ein Auge auf die Zeitzoneninformationen halten, wie Sie in Schwierigkeiten geraten könnten, wenn nicht-tz-aware Datetimes mit tz-aware diejenigen verglichen wird.
Es ist wahrscheinlich das beste Produkt immer sie machen tz-aware (wenn auch nur als UTC), wenn Sie wirklich wissen, warum es nicht von Nutzen wäre, dies zu tun.
#-----------------------------------------------
import datetime
import pytz
import dateutil.parser
#-----------------------------------------------
utc = pytz.utc
BERLIN = pytz.timezone('Europe/Berlin')
#-----------------------------------------------
def to_iso8601(when=None, tz=BERLIN):
if not when:
when = datetime.datetime.now(tz)
if not when.tzinfo:
when = tz.localize(when)
_when = when.strftime("%Y-%m-%dT%H:%M:%S.%f%z")
return _when[:-8] + _when[-5:] # Remove microseconds
#-----------------------------------------------
def from_iso8601(when=None, tz=BERLIN):
_when = dateutil.parser.parse(when)
if not _when.tzinfo:
_when = tz.localize(_when)
return _when
#-----------------------------------------------
Ich habe es noch nicht ausprobiert, aber pyiso8601 verspricht, dies zu unterstützen.
isodate scheint die umfassendste Unterstützung zu haben.
Beide Möglichkeiten:
Epoch ISO Zeit:
isoTime = time.strftime('%Y-%m-%dT%H:%M:%SZ', time.gmtime(epochTime))
ISO Zeit Epoche:
epochTime = time.mktime(time.strptime(isoTime, '%Y-%m-%dT%H:%M:%SZ'))
import datetime, time
def convert_enddate_to_seconds(self, ts):
"""Takes ISO 8601 format(string) and converts into epoch time."""
dt = datetime.datetime.strptime(ts[:-7],'%Y-%m-%dT%H:%M:%S.%f')+\
datetime.timedelta(hours=int(ts[-5:-3]),
minutes=int(ts[-2:]))*int(ts[-6:-5]+'1')
seconds = time.mktime(dt.timetuple()) + dt.microsecond/1000000.0
return seconds
Dazu gehört auch die Millisekunden und Zeitzone.
Wenn die Zeit '2012-09-30T15: 31: 50,262 bis 08: 00'., Diese in Epoche Zeit umwandeln
>>> import datetime, time
>>> ts = '2012-09-30T15:31:50.262-08:00'
>>> dt = datetime.datetime.strptime(ts[:-7],'%Y-%m-%dT%H:%M:%S.%f')+ datetime.timedelta(hours=int(ts[-5:-3]), minutes=int(ts[-2:]))*int(ts[-6:-5]+'1')
>>> seconds = time.mktime(dt.timetuple()) + dt.microsecond/1000000.0
>>> seconds
1348990310.26
Hier ist eine super einfache Möglichkeit, diese Art von Konvertierungen zu tun. Kein Parsing oder zusätzliche Bibliotheken erforderlich. Es ist sauber, einfach und schnell.
import datetime
import time
################################################
#
# Takes the time (in seconds),
# and returns a string of the time in ISO8601 format.
# Note: Timezone is UTC
#
################################################
def TimeToISO8601(seconds):
strKv = datetime.datetime.fromtimestamp(seconds).strftime('%Y-%m-%d')
strKv = strKv + "T"
strKv = strKv + datetime.datetime.fromtimestamp(seconds).strftime('%H:%M:%S')
strKv = strKv +"Z"
return strKv
################################################
#
# Takes a string of the time in ISO8601 format,
# and returns the time (in seconds).
# Note: Timezone is UTC
#
################################################
def ISO8601ToTime(strISOTime):
K1 = 0
K2 = 9999999999
K3 = 0
counter = 0
while counter < 95:
K3 = (K1 + K2) / 2
strK4 = TimeToISO8601(K3)
if strK4 < strISOTime:
K1 = K3
if strK4 > strISOTime:
K2 = K3
counter = counter + 1
return K3
################################################
#
# Takes a string of the time in ISO8601 (UTC) format,
# and returns a python DateTime object.
# Note: returned value is your local time zone.
#
################################################
def ISO8601ToDateTime(strISOTime):
return time.gmtime(ISO8601ToTime(strISOTime))
#To test:
Test = "2014-09-27T12:05:06.9876"
print ("The test value is: " + Test)
Ans = ISO8601ToTime(Test)
print ("The answer in seconds is: " + str(Ans))
print ("And a Python datetime object is: " + str(ISO8601ToDateTime(Test)))