2009-11-09 35 views

Respuesta

11

Eso probablemente no funcionará porque esas abreviaturas no son únicas. Ver this page para más detalles. Puede terminar teniendo que manejarlo usted mismo manualmente si está trabajando con un conjunto conocido de entradas.

+0

¿Es más fácil si lo limitamos a las zonas horarias en los EE. UU.? ¿Hay un conjunto "estándar" de abreviaturas en ese caso? –

+0

No olvide que "zonas horarias en los EE. UU." Incluye AKST, AKDT, HAST y HADT. Si solo quiere decir los 48 estados continentales, entonces solo tiene 8 zonas horarias de 3 letras para tratar (4 zonas horarias, horario estándar y horario de verano). – PaulMcG

+0

Aparentemente, algunos lugares usan HST y HDT como equivalentes para HAST y HADT también = \ –

5

La función parse() en dateutil no puede manejar zonas horarias. Lo que he estado usando es el formateador% Z y la función time.strptime(). No tengo idea de cómo lidia con la ambigüedad en las zonas horarias, pero parece indicar la diferencia entre CDT y CST, que es todo lo que necesitaba.

Antecedentes: Almazo imágenes de copia de seguridad en directorios cuyos nombres son marcas de tiempo usando la hora local, ya que no tengo relojes GMT a mano en casa. Así que uso time.strptime (d, r "% Y-% m-% dT% H:% M:% S_% Z") para analizar los nombres de los directorios nuevamente en un tiempo real para el análisis de edad.

+0

Según tengo entendido, strptime se ocupa de la ambigüedad al aceptar solo las horas indicadas en la configuración actual de la zona horaria. – Random832

55

dateutil 's parser.parse() acepta como argumento de palabra clave tzinfos un diccionario de la clase {'EST': -5*3600} (es decir, que coincide con el nombre de zona a GMT desplazamiento en segundos). Así que asumiendo que tenemos de eso, podemos hacer:

>>> import dateutil.parser as dp 
>>> s = 'Sat, 11/01/09 8:00PM' 
>>> for tz_code in ('PST','PDT','MST','MDT','CST','CDT','EST','EDT'): 
>>>  dt = s+' '+tz_code 
>>>  print dt, '=', dp.parse(dt, tzinfos=tzd) 

Sat, 11/01/09 8:00PM PST = 2009-11-01 20:00:00-08:00 
Sat, 11/01/09 8:00PM PDT = 2009-11-01 20:00:00-07:00 
Sat, 11/01/09 8:00PM MST = 2009-11-01 20:00:00-07:00 
Sat, 11/01/09 8:00PM MDT = 2009-11-01 20:00:00-06:00 
Sat, 11/01/09 8:00PM CST = 2009-11-01 20:00:00-06:00 
Sat, 11/01/09 8:00PM CDT = 2009-11-01 20:00:00-05:00 
Sat, 11/01/09 8:00PM EST = 2009-11-01 20:00:00-05:00 
Sat, 11/01/09 8:00PM EDT = 2009-11-01 20:00:00-04:00 

cuanto al contenido de tzinfos, aquí es cómo i pobladas mía:

tz_str = '''-12 Y 
-11 X NUT SST 
-10 W CKT HAST HST TAHT TKT 
-9 V AKST GAMT GIT HADT HNY 
-8 U AKDT CIST HAY HNP PST PT 
-7 T HAP HNR MST PDT 
-6 S CST EAST GALT HAR HNC MDT 
-5 R CDT COT EASST ECT EST ET HAC HNE PET 
-4 Q AST BOT CLT COST EDT FKT GYT HAE HNA PYT 
-3 P ADT ART BRT CLST FKST GFT HAA PMST PYST SRT UYT WGT 
-2 O BRST FNT PMDT UYST WGST 
-1 N AZOT CVT EGT 
0 Z EGST GMT UTC WET WT 
1 A CET DFT WAT WEDT WEST 
2 B CAT CEDT CEST EET SAST WAST 
3 C EAT EEDT EEST IDT MSK 
4 D AMT AZT GET GST KUYT MSD MUT RET SAMT SCT 
5 E AMST AQTT AZST HMT MAWT MVT PKT TFT TJT TMT UZT YEKT 
6 F ALMT BIOT BTT IOT KGT NOVT OMST YEKST 
7 G CXT DAVT HOVT ICT KRAT NOVST OMSST THA WIB 
8 H ACT AWST BDT BNT CAST HKT IRKT KRAST MYT PHT SGT ULAT WITA WST 
9 I AWDT IRKST JST KST PWT TLT WDT WIT YAKT 
10 K AEST ChST PGT VLAT YAKST YAPT 
11 L AEDT LHDT MAGT NCT PONT SBT VLAST VUT 
12 M ANAST ANAT FJT GILT MAGST MHT NZST PETST PETT TVT WFT 
13 FJST NZDT 
11.5 NFT 
10.5 ACDT LHST 
9.5 ACST 
6.5 CCT MMT 
5.75 NPT 
5.5 SLT 
4.5 AFT IRDT 
3.5 IRST 
-2.5 HAT NDT 
-3.5 HNT NST NT 
-4.5 HLV VET 
-9.5 MART MIT''' 

tzd = {} 
for tz_descr in map(str.split, tz_str.split('\n')): 
    tz_offset = int(float(tz_descr[0]) * 3600) 
    for tz_code in tz_descr[1:]: 
     tzd[tz_code] = tz_offset 

ps. por @Hank La nomenclatura de la zona horaria gay no está claramente definida. Para formar mi mesa, utilicé http://www.timeanddate.com/library/abbreviations/timezones/ y http://en.wikipedia.org/wiki/List_of_time_zone_abbreviations. Miré cada conflicto y resolví conflictos entre nombres oscuros y populares hacia los populares (más usados). Había uno - IST - que no era tan sencillo (que puede significar indio hora estándar, Irán hora estándar, irlandesa hora estándar o Israel Standard Time), así que lo dejé fuera de la tabla: es posible que deba elegir qué agregar según su ubicación. Ah, y dejé fuera la República de Kiribati con su absurda "mírame, soy el primero en celebrar Año Nuevo" GMT + 13 y GMT + 14 zonas horarias.

+3

¡práctico, simple y ordenado! –

+1

No puedo hacer que [ChST] (http://en.wikipedia.org/wiki/Chamorro_Time_Zone) trabaje. Esa ** h ** minúscula parece causar problemas. Tuve que usar mayúscula CHST en la lista de zonas horarias y hacer 'dp.parse (dt, tzinfos = tzd)' –

+0

el diccionario es incorrecto; por ejemplo, MSK en 2012/12 tiene un desplazamiento de 4 horas, pero solo 3 horas en los años anteriores – jfs

9

Usted puede tratar de módulo pytz: http://pytz.sourceforge.net/

pytz trae la base de datos de Olson tz en Python. Esta biblioteca permite realizar cálculos precisos de y de zona horaria multiplataforma utilizando Python 2.3 o superior. También resuelve el problema de veces ambiguas al final del horario de verano de ahorro, que puede leer más sobre en la Biblioteca de Python Referencia (datetime.tzinfo).

Casi todas las zonas horarias de Olson son compatibles con .

+1

tengo curiosidad, ¿cómo se puede analizar "Sat, 11/01/09 8:00 PM EST" con dicha pytz? –

+0

honestamente, no se puede resolver porque la abreviatura no es uno a uno. La buena noticia es que pytz ya ha proporcionado el mapeo (de uno a muchos) y los programadores solo pueden elegir los mapeos deseados. – Drake

+2

@NasBanov: 'EST' es ambiguo, pero [puede usar pytz para enumerar todas las interpretaciones posibles] (http://stackoverflow.com/a/13713813/4279). – jfs

0

I utilizarse pytz para generar una TZINFOS mapeo:

from datetime import datetime as dt 

import pytz 

from dateutil.tz import gettz 
from pytz import utc 
from dateutil import parser 


def gen_tzinfos(): 
    for zone in pytz.common_timezones: 
     try: 
      tzdate = pytz.timezone(zone).localize(dt.utcnow(), is_dst=None) 
     except pytz.NonExistentTimeError: 
      pass 
     else: 
      tzinfo = gettz(zone) 

      if tzinfo: 
       yield tzdate.tzname(), tzinfo 

TZINFOS Uso

>>> TZINFOS = dict(gen_tzinfos()) 
>>> TZINFOS 
{'+02': tzfile('/usr/share/zoneinfo/Antarctica/Troll'), 
'+03': tzfile('/usr/share/zoneinfo/Europe/Volgograd'), 
'+04': tzfile('Europe/Ulyanovsk'), 
'+05': tzfile('/usr/share/zoneinfo/Indian/Kerguelen'),    
... 
'WGST': tzfile('/usr/share/zoneinfo/America/Godthab'), 
'WIB': tzfile('/usr/share/zoneinfo/Asia/Pontianak'), 
'WIT': tzfile('/usr/share/zoneinfo/Asia/Jayapura'), 
'WITA': tzfile('/usr/share/zoneinfo/Asia/Makassar'), 
'WSDT': tzfile('/usr/share/zoneinfo/Pacific/Apia'), 
'XJT': tzfile('/usr/share/zoneinfo/Asia/Urumqi')} 

parser Uso

>>> date_str = 'Sat, 11/01/09 8:00PM EST' 
>>> tzdate = parser.parse(date_str, tzinfos=TZINFOS) 
>>> tzdate.astimezone(utc) 
datetime.datetime(2009, 11, 2, 1, 0, tzinfo=<UTC>) 

La conversión UTC es necesidad ed ya que hay muchas zonas horarias disponibles para cada abreviatura. Como TZINFOS es dict, solo tiene la última zona horaria por abreviatura. Y es posible que no obtenga el que esperaba antes de la conversión.

>>> tzdate 
datetime.datetime(2009, 11, 1, 20, 0, tzinfo=tzfile('/usr/share/zoneinfo/America/Port-au-Prince')) 
Cuestiones relacionadas