Generar marca de tiempo RFC 3339 en Python
datetime iso8601 (7)
De hecho, puede utilizar el módulo datetime incorporado. Como mentions , hay ejemplos en la página que muestran cómo. Si observa la sección en tzinfo , verá un ejemplo largo que muestra muchos casos de uso diferentes. Aquí está el código para el que está buscando, que es generar una marca de tiempo UTC RFC 3339.
from datetime import tzinfo, timedelta, datetime
import time as _time
ZERO = timedelta(0)
STDOFFSET = timedelta(seconds=-_time.timezone)
if _time.daylight:
DSTOFFSET = timedelta(seconds=-_time.altzone)
else:
DSTOFFSET = STDOFFSET
DSTDIFF = DSTOFFSET - STDOFFSET
class LocalTimezone(tzinfo):
def utcoffset(self, dt):
if self._isdst(dt):
return DSTOFFSET
else:
return STDOFFSET
def dst(self, dt):
if self._isdst(dt):
return DSTDIFF
else:
return ZERO
def tzname(self, dt):
return _time.tzname[self._isdst(dt)]
def _isdst(self, dt):
tt = (dt.year, dt.month, dt.day,
dt.hour, dt.minute, dt.second,
dt.weekday(), 0, 0)
stamp = _time.mktime(tt)
tt = _time.localtime(stamp)
return tt.tm_isdst > 0
Local = LocalTimezone()
d = datetime.now(Local)
print d.isoformat(''T'')
# which returns
# 2014-04-28T15:44:45.758506-07:00
Estoy tratando de generar una marca de tiempo UTC RFC 3339 en Python. Hasta ahora he podido hacer lo siguiente:
>>> d = datetime.datetime.now()
>>> print d.isoformat(''T'')
2011-12-18T20:46:00.392227
Mi problema es con la configuración de la compensación UTC.
De acuerdo con los docs , el classmethod datetime.now([tz])
toma un argumento tz
opcional donde tz must be an instance of a class tzinfo subclass
, y datetime.tzinfo
es an abstract base class for time zone information objects.
Aquí es donde me pierdo. ¿Cómo es que tzinfo es una clase abstracta y cómo se supone que debo implementarla?
( NOTA: en PHP es tan simple como timestamp = date(DATE_RFC3339);
por lo que no puedo entender por qué el enfoque de Python es tan complicado).
El paquete pytz está disponible para Python 2.X y 3.X. Implementa subclases concretas de tzinfo
, entre otros servicios, para que no tenga que hacerlo.
Para agregar un desplazamiento UTC: importar fecha y hora importar pytz
dt = datetime.datetime(2011, 12, 18, 20, 46, 00, 392227)
utc_dt = pytz.UTC.localize(dt)
Y ahora esto:
print utc_dt.isoformat()
imprimiría:
2011-12-18T20:46:00.392227+00:00
En Python 3.3+:
>>> from datetime import datetime, timezone
>>> local_time = datetime.now(timezone.utc).astimezone()
>>> local_time.isoformat()
''2015-01-16T16:52:58.547366+01:00''
En versiones anteriores de Python, si todo lo que necesita es un objeto datetime que represente la hora actual en UTC, entonces podría definir una subclase tzinfo simple como se muestra en los documentos para representar la zona horaria UTC :
from datetime import datetime
utc_now = datetime.now(utc)
print(utc_now.isoformat(''T''))
# -> 2015-05-19T20:32:12.610841+00:00
También puede usar el módulo tzlocal
para obtener la pytz
horaria de pytz
representa su zona horaria local:
#!/usr/bin/env python
from datetime import datetime
from tzlocal import get_localzone # $ pip install tzlocal
now = datetime.now(get_localzone())
print(now.isoformat(''T''))
Funciona tanto en Python 2 como en 3.
Las zonas horarias son un problema, por lo que es probable que hayan optado por no incluirlas en la biblioteca datetime.
prueba pytz, tiene el tzinfo que buscas: http://pytz.sourceforge.net/
Primero debe crear el objeto de datetime
, luego aplicar la zona horaria como se muestra a continuación, y luego su salida .isoformat()
incluirá el desplazamiento UTC como se desee:
d = datetime.datetime.utcnow()
d_with_timezone = d.replace(tzinfo=pytz.UTC)
d_with_timezone.isoformat()
''2017-04-13T14: 34: 23.111142 + 00: 00''
O simplemente use UTC y lance una "Z" (para la zona horaria Zulu ) al final para marcar la "zona horaria" como UTC.
d = datetime.datetime.utcnow() # <-- get time in UTC
print d.isoformat("T") + "Z"
''2017-04-13T14: 34: 23.111142Z''
Luché mucho con el formato de fecha y hora RFC3339, pero encontré una solución adecuada para convertir date_string <=> datetime_object en ambas direcciones.
Necesita dos módulos externos diferentes, porque uno de ellos solo es capaz de hacer la conversión en una dirección (desafortunadamente):
primera instalación:
sudo pip install rfc3339
sudo pip install iso8601
luego incluye:
import datetime # for general datetime object handling
import rfc3339 # for date object -> date string
import iso8601 # for date string -> date object
Para no tener que recordar qué módulo es para qué dirección, escribí dos funciones simples de ayuda:
def get_date_object(date_string):
return iso8601.parse_date(date_string)
def get_date_string(date_object):
return rfc3339.rfc3339(date_object)
que dentro de tu código puedes usar fácilmente así:
input_string = ''1989-01-01T00:18:07-05:00''
test_date = get_date_object(input_string)
# >>> datetime.datetime(1989, 1, 1, 0, 18, 7, tzinfo=<FixedOffset ''-05:00'' datetime.timedelta(-1, 68400)>)
test_string = get_date_string(test_date)
# >>> ''1989-01-01T00:18:07-05:00''
test_string is input_string # >>> True
Heureka! Ahora puede ( jaja ) usar fácilmente las cadenas de fecha y las cadenas de fecha en un formato utilizable.
Otra utilidad útil con la que comencé a trabajar: la biblioteca dateutil para el manejo de la zona horaria y el análisis de fechas Recomendado alrededor de SO, incluyendo esta answer
Más abajo en el mismo documento al que se vinculó, explica cómo implementarlo, dando algunos ejemplos, incluido el código completo para una clase UTC
(que representa UTC), una clase FixedOffset
(que representa una zona horaria con un desplazamiento fijo de UTC, como opuesto a una zona horaria con DST y otras cosas), y algunos otros.