2010-05-04 5 views
2

Как и в заголовке, я пытаюсь проанализировать XML-файл, содержащий тип данных xs:duration. Я хотел бы преобразовать это в объект Python timedelta, который затем я могу использовать в дальнейших вычислениях.Анализ синтаксиса xs: длительность в объект Python datetime.timedelta?

Есть ли какой-либо встроенный способ сделать это, аналогично функции strptime()? Если нет, то каков наилучший способ добиться этого?

ответ

3

Увидев, что у меня уже есть рабочий пример того, что я задал в вопросе, я отправлю его здесь для полноты. Если появятся какие-то лучшие ответы, я соглашусь.

period = '-P14D' 
regex = re.compile('(?P<sign>-?)P(?:(?P<years>\d+)Y)?(?:(?P<months>\d+)M)?(?:(?P<days>\d+)D)?(?:T(?:(?P<hours>\d+)H)?(?:(?P<minutes>\d+)M)?(?:(?P<seconds>\d+)S)?)?') 

# Fetch the match groups with default value of 0 (not None) 
duration = regex.match(period).groupdict(0) 

# Create the timedelta object from extracted groups 
delta = timedelta(days=int(duration['days']) + (int(duration['months']) * 30) + (int(duration['years']) * 365), 
        hours=int(duration['hours']), 
        minutes=int(duration['minutes']), 
        seconds=int(duration['seconds'])) 

if duration['sign'] == "-": 
    delta *= -1 

Это работает, но не будет обрабатывать месячные длины или високосные годы правильно. Для моих целей это не проблема, но стоит иметь в виду.

+1

Это работало отлично подходит для меня, пока мой приятель не добавил миллисекунды его значения. Может ли кто-нибудь обновить это регулярное выражение для обработки таких значений, как «P0Y0M0DT1H20M39.123S»? Благодаря! –

+0

'(? P -?) P (? :(? P \ d +) Y)? (? :(? P \ d +) M)? (? :(? P \ d +) D)? (?: T (? :(? P \ d +) H)? (? :(? P \ d +) M)? (? :(? P \ d + [.]? \ D *) S)?) ? ', если вам нужны десятичные числа в секундах – xvronny

4

Это старый вопрос, но для справок в будущем: для этого вы можете использовать isodate.parse_duration(). Он возвращает класс, совместимый с timedelta.

См https://pypi.python.org/pypi/isodate

+1

' '' isodate.parse_duration ('P0Y0M0DT1H20M39.123S') '' 'превращается в' '' datetime.timedelta (0, 4839, 123000) '' ' – iuridiniz