2014-01-09 4 views
10

Я анализирую некоторые данные, которые имеют временное время timestampe leapsecond 2012-06-30T23:59:60.209215. Я использовал следующий код для разбора этой строки и преобразовать в объект даты и времени:Python - Datetime не учитывает прыжок второй правильно?

nofrag, frag = t.split('.') 
    nofrag_dt = datetime.datetime.strptime(nofrag, "%Y-%m-%dT%H:%M:%S") 
    dt = nofrag_dt.replace(microsecond=int(frag)) 

Python документация утверждает, что это не должно быть проблемой, как %S принимает [0, 61]. Но, я получаю эту ошибку с выше отметки времени

nofrag_dt = datetime.datetime.strptime(nofrag, "%Y-%m-%dT%H:%M:%S") 
ValueError: second must be in 0..59 

Благодарности

+3

Где документация утверждает, что? http://docs.python.org/2/library/datetime.html говорит: «В отличие от модуля времени, модуль datetime не поддерживает прыжки секунд». – geoffspear

+0

http://docs.python.org/2/library/datetime.html#datetime.datetime.strptime указывает на http://docs.python.org/2/library/time.html#time.strptime, где http : //docs.python.org/2/library/time.html#time.strftime утверждает, что поддерживает второй прыжок – madtowneast

+0

Ah. Проблема не в синтаксическом анализе; это делается 'time.strptime' и работает нормально; проблема заключается в том, что если секунды> 59, их нельзя преобразовать обратно в 'datetime.datetime'. – geoffspear

ответ

1

ли это:

import time 
import datetime 
t = '2012-06-30T23:59:60.209215' 
nofrag, frag = t.split('.') 
nofrag_dt = time.strptime(nofrag, "%Y-%m-%dT%H:%M:%S") 
ts = datetime.datetime.fromtimestamp(time.mktime(nofrag_dt)) 
dt = ts.replace(microsecond=int(frag)) 
print(dt) 

Выход:

2012-07-01 00:00:00.209215 
+0

примечание: кругосветное путешествие по местному времени может завершиться неудачно (например, во время перехода на летнее время), и это не нужно *, поскольку [мой ответ демонстрирует] (http://stackoverflow.com/a/21029510/4279). – jfs

8

The documentation for %S says:

В отличие от модуля времени, модуль datetime не поддерживает скачки секунд.

строка время "2012-06-30T23:59:60.209215" означает, что время в UTC (это последний прыжок второе на данный момент):

import time 
from calendar import timegm 
from datetime import datetime, timedelta 

time_string = '2012-06-30T23:59:60.209215' 
time_string, dot, us = time_string.partition('.') 
utc_time_tuple = time.strptime(time_string, "%Y-%m-%dT%H:%M:%S") 
dt = datetime(1970, 1, 1) + timedelta(seconds=timegm(utc_time_tuple)) 
if dot: 
    dt = dt.replace(microsecond=datetime.strptime(us, '%f').microsecond) 
print(dt) 
# -> 2012-07-01 00:00:00.209215 
+0

Как это подразумевается, что время в UTC? Я не вижу конца 'Z' или' +00: 00'. –

+0

@MattJohnson: найдите время последней секунды прыжка (это тот же момент времени во всем мире). – jfs

+0

Ах! Очень хорошо! Тут ты меня подловил! :) –

Смежные вопросы