Wie kann ich eine ISO 8601-Datetime-Zeichenfolge in einen Python Datetime-Objekt übersetzen? [Duplikat]

StackOverflow https://stackoverflow.com/questions/969285

Frage

    

Diese Frage bereits eine Antwort hier:

         

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?

War es hilfreich?

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

aniso8601 sollte damit umgehen. Es versteht auch, Zeitzonen, Python 2 und Python 3, und es hat eine angemessene Berichterstattung über den Rest ISO 8601 , sollten Sie müssen es immer.

import aniso8601
aniso8601.parse_datetime('2007-03-04T21:08:12')

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)))
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top