example change biblioteca python datetime timezone

change - strftime python



¿Cómo se analizan las fechas con una cadena de zona horaria de-0400 en Python? (6)

Tengo una cadena de fecha del formulario ''2009/05/13 19:19:30 -0400''. Parece que las versiones anteriores de Python pueden haber admitido una etiqueta de formato% z en strptime para la especificación de zona horaria posterior, pero 2.6.x parece haber eliminado eso.

¿Cuál es la forma correcta de analizar esta cadena en un objeto datetime?


Aquí hay una solución al problema de "%z" para Python 2.7 y versiones anteriores

En lugar de usar:

datetime.strptime(t,''%Y-%m-%dT%H:%M %z'')

Usa el timedelta para tener en cuenta la zona horaria, así:

from datetime import datetime,timedelta def dt_parse(t): ret = datetime.strptime(t[0:16],''%Y-%m-%dT%H:%M'') if t[18]==''+'': ret-=timedelta(hours=int(t[19:22]),minutes=int(t[23:])) elif t[18]==''-'': ret+=timedelta(hours=int(t[19:22]),minutes=int(t[23:])) return ret

Tenga en cuenta que las fechas se convertirían a GMT , lo que permitiría hacer aritmética de fecha sin preocuparse por las zonas horarias.


El problema con el uso de dateutil es que no se puede tener la misma cadena de formato tanto para la serialización como para la deserialización, ya que dateutil tiene opciones de formato limitadas (solo el dayfirst y el yearfirst ).

En mi aplicación, almaceno la cadena de formato en el archivo .INI, y cada implementación puede tener su propio formato. Por lo tanto, realmente no me gusta el enfoque dateutil.

Aquí hay un método alternativo que usa pytz en su lugar:

from datetime import datetime, timedelta from pytz import timezone, utc from pytz.tzinfo import StaticTzInfo class OffsetTime(StaticTzInfo): def __init__(self, offset): """A dumb timezone based on offset such as +0530, -0600, etc. """ hours = int(offset[:3]) minutes = int(offset[0] + offset[3:]) self._utcoffset = timedelta(hours=hours, minutes=minutes) def load_datetime(value, format): if format.endswith(''%z''): format = format[:-2] offset = value[-5:] value = value[:-5] return OffsetTime(offset).localize(datetime.strptime(value, format)) return datetime.strptime(value, format) def dump_datetime(value, format): return value.strftime(format) value = ''2009/05/13 19:19:30 -0400'' format = ''%Y/%m/%d %H:%M:%S %z'' assert dump_datetime(load_datetime(value, format), format) == value assert datetime(2009, 5, 13, 23, 19, 30, tzinfo=utc) / .astimezone(timezone(''US/Eastern'')) == load_datetime(value, format)


Puede usar la función de análisis de dateutil:

>>> from dateutil.parser import parse >>> d = parse(''2009/05/13 19:19:30 -0400'') >>> d datetime.datetime(2009, 5, 13, 19, 19, 30, tzinfo=tzoffset(None, -14400))

De esta forma, obtienes un objeto datetime que puedes usar.

Como se answered , dateutil2.0 está escrito para Python 3.0 y no funciona con Python 2.x. Para Python 2.x se necesita usar dateutil1.5.


Si está en Linux, puede usar el comando de date externo para dwim:

import commands, datetime def parsedate(text): output=commands.getoutput(''date -d "%s" +%%s'' % text ) try: stamp=eval(output) except: print output raise return datetime.datetime.frometimestamp(stamp)

Esto es, por supuesto, menos portátil que dateutil, pero un poco más flexible, porque la date también aceptará entradas como "ayer" o "el año pasado" :-)


Un trazador de líneas para los viejos pitones hacia fuera allí. Puedes multiplicar un timedelta por 1 / -1 dependiendo de +/- signo, como en:

datetime.strptime(s[:19], ''%Y-%m-%dT%H:%M:%S'') + timedelta(hours=int(s[20:22]), minutes=int(s[23:])) * (-1 if s[19] == ''+'' else 1)


%z es compatible con Python 3.2+:

>>> from datetime import datetime >>> datetime.strptime(''2009/05/13 19:19:30 -0400'', ''%Y/%m/%d %H:%M:%S %z'') datetime.datetime(2009, 5, 13, 19, 19, 30, tzinfo=datetime.timezone(datetime.timedelta(-1, 72000)))

En versiones anteriores:

from datetime import datetime date_str = ''2009/05/13 19:19:30 -0400'' naive_date_str, _, offset_str = date_str.rpartition('' '') naive_dt = datetime.strptime(naive_date_str, ''%Y/%m/%d %H:%M:%S'') offset = int(offset_str[-4:-2])*60 + int(offset_str[-2:]) if offset_str[0] == "-": offset = -offset dt = naive_dt.replace(tzinfo=FixedOffset(offset)) print(repr(dt)) # -> datetime.datetime(2009, 5, 13, 19, 19, 30, tzinfo=FixedOffset(-240)) print(dt) # -> 2009-05-13 19:19:30-04:00

donde FixedOffset es una clase basada en el ejemplo de código de los documentos :

from datetime import timedelta, tzinfo class FixedOffset(tzinfo): """Fixed offset in minutes: `time = utc_time + utc_offset`.""" def __init__(self, offset): self.__offset = timedelta(minutes=offset) hours, minutes = divmod(offset, 60) #NOTE: the last part is to remind about deprecated POSIX GMT+h timezones # that have the opposite sign in the name; # the corresponding numeric value is not used e.g., no minutes self.__name = ''<%+03d%02d>%+d'' % (hours, minutes, -hours) def utcoffset(self, dt=None): return self.__offset def tzname(self, dt=None): return self.__name def dst(self, dt=None): return timedelta(0) def __repr__(self): return ''FixedOffset(%d)'' % (self.utcoffset().total_seconds() / 60)