Рубрики
Без рубрики

Разбор строк Datetime с помощью parsedatetime в Python

В этом уроке мы рассмотрим, как анализировать строки datetime в Python с помощью parsedatetime, включая часовые пояса и локали, с примерами.

Автор оригинала: Guest Contributor.

Вступление

В этом уроке мы рассмотрим как анализировать Datetime с помощью parsedatetime в Python .

Чтобы использовать пакет parsedatetime , нам сначала нужно установить его с помощью pip:

$ pip install parsedatetime

Если pip install parsedatetime не удастся, пакет также будет доступен с открытым исходным кодом на Github .

Преобразование строки в объект Datetime Python с помощью parsedatetime

Первый и наиболее распространенный способ использования parsedatetime – это синтаксический анализ строки в объект datetime . Во-первых, вам нужно импортировать библиотеку parsedatetime и создать экземпляр объекта Calendar , который выполняет фактический ввод, синтаксический анализ и манипулирование датами:

import parsedatetime
calendar = parsedatetime.Calendar()

Теперь мы можем вызвать метод parse() экземпляра calendar со строкой в качестве аргумента. Вы можете вставить обычные строки в формате datetime, такие как 1-1-2021 или читаемые человеком значения, такие как завтра , вчера , в следующем году , на прошлой неделе , обед завтра и т. Д… Мы также можем использовать 'End of Day' структуры с tomorrow eod

Давайте преобразуем datetime и читаемую человеком строку в объект datetime с помощью parsedatetime :

import parsedatetime
from datetime import datetime

calendar = parsedatetime.Calendar()

print(calendar.parse('tomorrow'))
print(calendar.parse('1-1-2021'))

Это приводит к двум печатным кортежам:

(time.struct_time(tm_year=2021, tm_mon=3, tm_mday=19, tm_hour=9, tm_min=0, tm_sec=0, tm_wday=4, tm_yday=78, tm_isdst=-1), 1)
(time.struct_time(tm_year=2021, tm_mon=1, tm_mday=1, tm_hour=18, tm_min=5, tm_sec=14, tm_wday=3, tm_yday=77, tm_isdst=0), 1)

Это не очень читабельно для человека… Возвращаемый кортеж для каждого преобразования состоит из объекта struct_time , который содержит такую информацию, как год, месяц, день месяца и т. Д. Второе значение – это код состояния – целое число, обозначающее, как прошло преобразование.

0 означает неудачный синтаксический анализ, 1 означает успешный синтаксический анализ до даты , 2 означает успешный разбор на время и 3 означает успешный синтаксический анализ в datetime .

Давайте разберем этот вывод:

print(calendar.parse('tomorrow')[0].tm_mday)
print(calendar.parse('1-1-2021')[0].tm_mday)

Этот код приводит к:

19
1

С другой стороны, мы получаем здесь только день месяца. Обычно мы хотели бы вывести что-то похожее на формат ГГГГ-мм-дд ЧЧ:мм:сс или любую его вариацию.

К счастью, мы можем легко использовать результат time.struct_time и сгенерировать с ним обычный Python datetime :

import parsedatetime
from datetime import datetime

calendar = parsedatetime.Calendar()

time_structure_tomorrow, parse_status_tomorrow = calendar.parse('tomorrow')
time_structure_2021, parse_status_2021 = calendar.parse('1-1-2021')

print(datetime(*time_structure_tomorrow[:6]))
print(datetime(*time_structure_2021[:6]))

Конструктору datetime() не нужна вся информация из временной структуры , предоставляемой parsedatetime , поэтому мы ее нарезали.

Этот код приводит к:

2021-03-19 09:00:00
2021-01-01 18:11:06

Имейте в виду, что дата и время 1 января учитывали время исполнения.

Обработка часовых поясов

Иногда ваше приложение может принимать во внимание часовые пояса ваших конечных пользователей. Для поддержки часового пояса мы обычно используем пакет Pytz , хотя вы можете использовать и другие пакеты.

Давайте установим Pytz через pip :

$ pip install pytz

Теперь мы можем импортировать пакеты parsedatetime и pytz в скрипт и создать стандартный экземпляр Calendar :

import parsedatetime
import pytz
from pytz import timezone

calendar = parsedatetime.Calendar()

Давайте взглянем на поддерживаемые часовые пояса, распечатав all_timezones :

print(pytz.all_timezones)

Этот код приведет к огромному списку всех доступных часовых поясов:

['Africa/Abidjan', 'Africa/Accra', 'Africa/Addis_Ababa', 'Africa/Algiers', ...]

Давайте выберем один из них, например первый, и передадим его в качестве аргумента tzinfo функции Calendar ‘ s parse () . Кроме того, мы хотим предоставить аргумент datetime String , который является фактической строкой, которую мы хотим разобрать:

datetime_object, status = calendar.parseDT(datetimeString='tomorrow', tzinfo=timezone('Africa/Abidjan'))

Этот метод возвращает кортеж объекта Datetime и код состояния преобразования, который является целым числом – 1 что означает “успешный”, и 0 что означает “неуспешный”.

Давайте продолжим и напечатаем datetime_object :

print(datetime_object)

Этот код приводит к:

2021-03-16 09:00:00+00:00

Календарь.Парседат()

В то время как Calendar.parse() является методом синтаксического анализа общего уровня, который возвращает кортеж с кодом состояния и time.struct_time , метод parseDate() является методом, предназначенным для кратких строковых дат, и просто возвращает читаемый человеком результат:

import parsedatetime
calendar = parsedatetime.Calendar()

result = calendar.parseDate('5/5/91')
print(result)

result теперь содержит вычисленное struct_time значение даты, которую мы передали:

(1991, 5, 5, 14, 31, 18, 0, 74, 0)

Но что мы делаем, когда хотим разобрать 5 мая 2077 года? Мы можем попробовать запустить следующий код:

import parsedatetime
calendar = parsedatetime.Calendar()
result = calendar.parseDate('5/5/77')
print(result)

Однако этот код приведет к:

(1977, 5, 5, 14, 36, 21, 0, 74, 0)

Calendar.parseDate() ошибочно принял краткую дату за более реалистичную 1977 . Мы можем решить эту проблему двумя способами:

  • Просто укажите полный год – 2077 :
import parsedatetime
calendar = parsedatetime.Calendar()
result = calendar.parseDate('5/5/2077')
print(result)
  • Используйте Эпоха дня рождения :
import parsedatetime
constants = parsedatetime.Constants()
constants.BirthdayEpoch = 80

# Pass our new constants to the Calendar
calendar = parsedatetime.Calendar(constants)
result = calendar.parseDate('5/5/77')
print(result)

Этот код приведет к:

(2077, 5, 5, 14, 39, 47, 0, 74, 0)

Вы можете получить доступ к содержимому библиотеки parsedatetime через объект Constants . Здесь мы установили Эпоху дня рождения на 80 .

Birthday Epoch управляет тем, как пакет обрабатывает двузначные годы, например 77 . Если анализируемое значение меньше значения, которое мы установили для Birthday Epoch – оно добавит анализируемое значение к 2000 . С тех пор как мы установили Эпоху дня рождения на 80 , и разобран 77 , он преобразует его в 2077 .

В противном случае он добавит анализируемое значение к 1900 .

Календарь.parseDateText()

Другой альтернативой решению проблемы ошибочных коротких дат является использование длинных дат. Для длинных дат можно использовать метод parseDateText() :

import parsedatetime

result2 = calendar.parseDateText('May 5th, 1991')
print(result2)

Этот код приведет к:

(1991, 5, 5, 14, 31, 46, 0, 74, 0)

Использование локалей

Наконец, мы можем использовать parsedatetime с locale information . Информация о локали поступает либо из PyICU , либо из ранее использованного класса Constants .

Внутренний класс Constants имеет множество атрибутов, как и атрибут Birthday Epoch . Два из них – LocaleID и userPyICU .

Давайте попробуем установить locale Id на испанский и установить usePyICU на False , так как мы не будем его использовать:

import parsedatetime

constants = parsedatetime.Constants(localeID='es', usePyICU=False)
calendar = parsedatetime.Calendar(constants)
result, code = calendar.parse('Marzo 28')
print(result)

Это приводит к:

(time.struct_time(tm_year=2021, tm_mon=3, tm_mday=28, tm_hour=15, tm_min=0, tm_sec=5, tm_wday=0, tm_yday=74, tm_isdst=0), 1)

Метод возвращает a struct_time , поэтому мы можем легко преобразовать его в a datetime :

print(datetime(*result[:6]))

Это приводит к:

2021-03-28 22:08:40

Вывод

В этом уроке мы рассмотрели несколько способов синтаксического анализа datetime с помощью пакета parsedatetime в Python.

Мы рассмотрели преобразование между строками и объектами datetime через parsedatetime , а также обработку часовых поясов с помощью pytz и локалей, используя Константы экземпляр библиотеки parsedatetime .