2012-07-12 6 views
5

Ho una lista di stringhe come segue:Python: metodo efficace per convertire le ore ambigue in oggetti temporali?

4:00-5:00PM 
11:00-2:00PM 
12:00-1:00PM 
11:00-1:00AM 

e sto cercando di trovare un modo efficace per creare due oggetti di tempo (suppongo che questo è l'unico modo per tenere traccia di un intervallo di tempo, che in seguito combinerò con un oggetto data). E 'chiaro per l'uomo ciò che intendiamo noi diciamo 11: 00-1: 00, ma chiedendo che cosa è un modo efficace per convertire questo:

datetime.time(23, 0) 
datetime.time(1, 0) 

Il mio approccio attuale è quello di prendere la prima volta, e creare un PM e la versione AM, prendi il timedelta con l'ora di fine (che è specificata) e prendi la più breve delle due differenze per essere quella corretta.

+0

È molto più facile aiutarti quando ci mostri (alcuni) il tuo codice. Inoltre, il tuo approccio all'interpretazione del valore della mano sinistra come AM e PM e la selezione del delta più piccolo è come lo farei anch'io. –

+0

wow questo è un sacco di codice, stai complicando l'implementazione. –

risposta

3

Ecco una semplice implementazione.

>>> def timeRange(timestr): 
    ...  t1, t2 = timestr.split("-") 
    ...  timeFormat = "%I:%M%p" 
    ...  t1AM = datetime.datetime.strptime(t1 + "AM", timeFormat) 
    ...  t1PM = datetime.datetime.strptime(t1 + "PM", timeFormat) 
    ...  t2 = datetime.datetime.strptime(t2, timeFormat) 
    ...  
    ...  if (t2 - t1AM).seconds < (t2-t1PM).seconds: 
    ...   return t1AM.time(), t2.time() 
    ...  else: 
    ...   return t1PM.time(), t2.time() 
    >>> timeRange("11:00-2:00PM") 
    (datetime.time(11, 0), datetime.time(14, 0)) 
    >>> timeRange("4:00-5:00PM") 
    (datetime.time(16, 0), datetime.time(17, 0)) 
    >>> timeRange("11:00-1:00AM") 
    (datetime.time(23, 0), datetime.time(1, 0)) 
    >>> timeRange("11:00-2:00PM") 
    (datetime.time(11, 0), datetime.time(14, 0)) 
    >>> timeRange("12:00-1:00PM") 
    (datetime.time(12, 0), datetime.time(13, 0)) 

Questo restituisce un oggetto time, ma si potrebbe rotolare che in un oggetto datetime se è necessario.

+0

Puoi aggiungere un altro indicatore nella tupla restituita per indicare che la seconda volta è il giorno successivo, ad esempio se la prima volta è PM e il secondo è AM. Ciò può aiutare nel calcolo della durata del periodo come richiesto nel PO. Altrimenti il ​​tempo (23, 0) -> il tempo (1, 0) sarebbe -22 ore ... –

+0

Impressionante! Grazie mille, ho provato una mia implementazione ed è molto simile alla tua, anche se la tua è più ottimizzata. – zhuyxn

2

Ci sono due ipotesi implicite nella tua domanda:

  • Siete alla ricerca per il minor tempo possibile tra questi tempi
  • La prima volta che è la prima delle due.

Se queste ipotesi sono vere, allora una rapida ottimizzazione sarebbe:

  • Se la prima volta è più grande rispetto al secondo (ad esempio, 11: 00-1: 00 o 11: 00-1: 00PM), quindi l'ora precedente è l'indicatore AM/PM "opposto" del secondo. In caso contrario, l'AM/PM della prima volta è uguale.

Questo funziona anche per il maggiore periodo di tempo, per esempio 6: 00-6: 00 (18:00-06:00 è più corta 06:00-06:00)

Una seconda osservazione è che non è possibile utilizzare l'oggetto orario semplice perché

  • Una durata AM-> PM si svolge su un limite di giorno (mezzanotte). Questo probabilmente sta rovinando il calcolo del tuo timedelta in questa condizione.

Quindi penso che si debba usare datetime, o avvolgere tutto in una struttura che indica l'ora nella prima volta che l'oggetto è il giorno precedente.

Spero che questo aiuti :)

+0

Hai ragione, ma devi fare attenzione a non trattare '6:00 AM-6:00AM' per avere la lunghezza 0. – glglgl

+0

6:00 AM-6:00AM non è conforme al formato fornito dall'OP - la prima volta nessun indicatore AM/PM –

+0

Esatto. Ma '6: 00-6: 00 AM' potrebbe essere inteso per essere' 6:00 AM-6:00AM' se '6:00 AM-6:00AM' ha lunghezza 0 ed è quindi più corto di' 6:00 PM-6:00AM ', che ha 12 ore in ogni caso. Se, tuttavia, '6:00 AM-6:00AM' significa avere 24 ore,' 6:00 PM-6:00AM' è più breve e quindi la soluzione.(Per essere completamente non ambigui, alcune parti del mondo potrebbero finalmente fare il passaggio che altre parti hanno già fatto circa 90 anni fa e scrivere '18: 00-06: 00 'in modo che tutti sappiano cosa si intende. SCNR) – glglgl

Problemi correlati