Автор оригинала: 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
.