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

datetime – манипуляции со значением даты и времени

Автор оригинала: Doug Hellmann.

Цель:

Модуль datetime включает функции и классы для выполнения анализ даты и времени, форматирование и арифметика.

datetime содержит функции и классы для работы с датой и временем, отдельно и вместе.

Раз

Значения времени представлены классом time . Экземпляр time имеет атрибуты для часа , минуты , секунды и микросекунды и может также включать информацию о часовом поясе.

datetime_time.py

import datetime

t  datetime.time(1, 2, 3)
print(t)
print('hour       :', t.hour)
print('minute     :', t.minute)
print('second     :', t.second)
print('microsecond:', t.microsecond)
print('tzinfo     :', t.tzinfo)

Аргументы для инициализации экземпляра time необязательны, но значение по умолчанию 0 вряд ли будет правильным.

$ python3 datetime_time.py

01:02:03
hour       : 1
minute     : 2
second     : 3
microsecond: 0
tzinfo     : None

Экземпляр time содержит только значения времени, а не дату, связанную со временем.

datetime_time_minmax.py

import datetime

print('Earliest  :', datetime.time.min)
print('Latest    :', datetime.time.max)
print('Resolution:', datetime.time.resolution)

Атрибуты класса min и max отражают допустимый диапазон времени в течение одного дня.

$ python3 datetime_time_minmax.py

Earliest  : 00:00:00
Latest    : 23:59:59.999999
Resolution: 0:00:00.000001

Разрешение для time ограничено целыми микросекундами.

datetime_time_resolution.py

import datetime

for m in [1, 0, 0.1, 0.6]:
    try:
        print('{:02.1f} :'.format(m),
              datetime.time(0, 0, 0, microsecondm))
    except TypeError as err:
        print('ERROR:', err)

Значения с плавающей запятой для микросекунд вызывают TypeError .

$ python3 datetime_time_resolution.py

1.0 : 00:00:00.000001
0.0 : 00:00:00
ERROR: integer argument expected, got float
ERROR: integer argument expected, got float

Даты

Значения календарной даты представлены классом date . Экземпляры имеют атрибуты для года , месяца и дня . С помощью метода класса today () легко создать дату, представляющую текущую дату.

datetime_date.py

import datetime

today  datetime.date.today()
print(today)
print('ctime  :', today.ctime())
tt  today.timetuple()
print('tuple  : tm_year  =', tt.tm_year)
print('         tm_mon   =', tt.tm_mon)
print('         tm_mday  =', tt.tm_mday)
print('         tm_hour  =', tt.tm_hour)
print('         tm_min   =', tt.tm_min)
print('         tm_sec   =', tt.tm_sec)
print('         tm_wday  =', tt.tm_wday)
print('         tm_yday  =', tt.tm_yday)
print('         tm_isdst =', tt.tm_isdst)
print('ordinal:', today.toordinal())
print('Year   :', today.year)
print('Mon    :', today.month)
print('Day    :', today.day)

В этом примере текущая дата выводится в нескольких форматах:

$ python3 datetime_date.py

2018-12-09
ctime  : Sun Dec  9 00:00:00 2018
tuple  : tm_year  = 2018
         tm_mon   = 12
         tm_mday  = 9
         tm_hour  = 0
         tm_min   = 0
         tm_sec   = 0
         tm_wday  = 6
         tm_yday  = 343
         tm_isdst = -1
ordinal: 737037
Year   : 2018
Mon    : 12
Day    : 9

Существуют также методы класса для создания экземпляров из меток времени POSIX или целых чисел, представляющих значения дат из григорианского календаря, где 1 января года 1 равно 1 , а каждый последующий день увеличивает значение на 1.

datetime_date_fromordinal.py

import datetime
import time

o  733114
print('o               :', o)
print('fromordinal(o)  :', datetime.date.fromordinal(o))

t  time.time()
print('t               :', t)
print('fromtimestamp(t):', datetime.date.fromtimestamp(t))

В этом примере показаны различные типы значений, используемые fromordinal () и fromtimestamp () .

$ python3 datetime_date_fromordinal.py

o               : 733114
fromordinal(o)  : 2008-03-13
t               : 1544370390.0430489
fromtimestamp(t): 2018-12-09

Как и в случае с time , диапазон поддерживаемых значений даты можно определить с помощью атрибутов min и max .

datetime_date_minmax.py

import datetime

print('Earliest  :', datetime.date.min)
print('Latest    :', datetime.date.max)
print('Resolution:', datetime.date.resolution)

Разрешение дат – целые дни.

$ python3 datetime_date_minmax.py

Earliest  : 0001-01-01
Latest    : 9999-12-31
Resolution: 1 day, 0:00:00

Другой способ создания новых экземпляров date использует метод replace () существующей date .

datetime_date_replace.py

import datetime

d1  datetime.date(2008, 3, 29)
print('d1:', d1.ctime())

d2  d1.replace(year2009)
print('d2:', d2.ctime())

В этом примере изменяется год, при этом день и месяц остаются неизменными.

$ python3 datetime_date_replace.py

d1: Sat Mar 29 00:00:00 2008
d2: Sun Mar 29 00:00:00 2009

timedeltas

Будущие и прошедшие даты могут быть вычислены с использованием базовой арифметики для двух объектов datetime или путем объединения datetime с timedelta . Вычитание дат дает timedelta , а timedelta можно добавить или вычесть из даты, чтобы получить другую дату. Внутренние значения для timedelta хранятся в днях, секундах и микросекундах.

datetime_timedelta.py

import datetime

print('microseconds:', datetime.timedelta(microseconds1))
print('milliseconds:', datetime.timedelta(milliseconds1))
print('seconds     :', datetime.timedelta(seconds1))
print('minutes     :', datetime.timedelta(minutes1))
print('hours       :', datetime.timedelta(hours1))
print('days        :', datetime.timedelta(days1))
print('weeks       :', datetime.timedelta(weeks1))

Значения промежуточного уровня, передаваемые конструктору, конвертируются в дни, секунды и микросекунды.

$ python3 datetime_timedelta.py

microseconds: 0:00:00.000001
milliseconds: 0:00:00.001000
seconds     : 0:00:01
minutes     : 0:01:00
hours       : 1:00:00
days        : 1 day, 0:00:00
weeks       : 7 days, 0:00:00

Полная продолжительность timedelta может быть получена как количество секунд с помощью total_seconds () .

datetime_timedelta_total_seconds.py

import datetime

for delta in [datetime.timedelta(microseconds1),
              datetime.timedelta(milliseconds1),
              datetime.timedelta(seconds1),
              datetime.timedelta(minutes1),
              datetime.timedelta(hours1),
              datetime.timedelta(days1),
              datetime.timedelta(weeks1),
              ]:
    print('{:15} = {:8} seconds'.format(
        str(delta), delta.total_seconds())
    )

Возвращаемое значение – число с плавающей запятой, чтобы учесть длительность менее секунды.

$ python3 datetime_timedelta_total_seconds.py

0:00:00.000001  =    1e-06 seconds
0:00:00.001000  =    0.001 seconds
0:00:01         =      1.0 seconds
0:01:00         =     60.0 seconds
1:00:00         =   3600.0 seconds
1 day, 0:00:00  =  86400.0 seconds
7 days, 0:00:00 = 604800.0 seconds

Дата Арифметика

В математике даты используются стандартные арифметические операторы.

datetime_date_math.py

import datetime

today  datetime.date.today()
print('Today    :', today)

one_day  datetime.timedelta(days1)
print('One day  :', one_day)

yesterday  today - one_day
print('Yesterday:', yesterday)

tomorrow  today + one_day
print('Tomorrow :', tomorrow)

print()
print('tomorrow - yesterday:', tomorrow - yesterday)
print('yesterday - tomorrow:', yesterday - tomorrow)

Этот пример с объектами даты иллюстрирует использование объектов timedelta для вычисления новых дат и вычитания экземпляров даты для создания timedelta (включая отрицательное значение дельты).

$ python3 datetime_date_math.py

Today    : 2018-12-09
One day  : 1 day, 0:00:00
Yesterday: 2018-12-08
Tomorrow : 2018-12-10

tomorrow - yesterday: 2 days, 0:00:00
yesterday - tomorrow: -2 days, 0:00:00

Объект timedelta также поддерживает арифметические операции с целыми числами, числами с плавающей запятой и другими экземплярами timedelta .

datetime_timedelta_math.py

import datetime

one_day  datetime.timedelta(days1)
print('1 day    :', one_day)
print('5 days   :', one_day * 5)
print('1.5 days :', one_day * 1.5)
print('1/4 day  :', one_day / 4)

# assume an hour for lunch
work_day  datetime.timedelta(hours7)
meeting_length  datetime.timedelta(hours1)
print('meetings per day :', work_day / meeting_length)

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

$ python3 datetime_timedelta_math.py

1 day    : 1 day, 0:00:00
5 days   : 5 days, 0:00:00
1.5 days : 1 day, 12:00:00
1/4 day  : 6:00:00
meetings per day : 7.0

Сравнение значений

Значения даты и времени можно сравнить с помощью стандартных операторов сравнения, чтобы определить, какое из них раньше или позже.

datetime_comparing.py

import datetime
import time

print('Times:')
t1  datetime.time(12, 55, 0)
print('  t1:', t1)
t2  datetime.time(13, 5, 0)
print('  t2:', t2)
print('  t1 < t2:', t1 < t2)

print()
print('Dates:')
d1  datetime.date.today()
print('  d1:', d1)
d2  datetime.date.today() + datetime.timedelta(days1)
print('  d2:', d2)
print('  d1 > d2:', d1 > d2)

Поддерживаются все операторы сравнения.

$ python3 datetime_comparing.py

Times:
  t1: 12:55:00
  t2: 13:05:00
  t1 < t2: True

Dates:
  d1: 2018-12-09
  d2: 2018-12-10
  d1 > d2: False

Объединение даты и времени

Используйте класс datetime для хранения значений, состоящих из компонентов даты и времени. Как и в случае с date , существует несколько удобных методов класса, позволяющих создавать экземпляры datetime из других общих значений.

datetime_datetime.py

import datetime

print('Now    :', datetime.datetime.now())
print('Today  :', datetime.datetime.today())
print('UTC Now:', datetime.datetime.utcnow())
print()

FIELDS  [
    'year', 'month', 'day',
    'hour', 'minute', 'second',
    'microsecond',
]

d  datetime.datetime.now()
for attr in FIELDS:
    print('{:15}: {}'.format(attr, getattr(d, attr)))

Как и следовало ожидать, экземпляр datetime имеет все атрибуты как объекта date , так и объекта time .

$ python3 datetime_datetime.py

Now    : 2018-12-09 10:46:30.494767
Today  : 2018-12-09 10:46:30.494806
UTC Now: 2018-12-09 15:46:30.494812

year           : 2018
month          : 12
day            : 9
hour           : 10
minute         : 46
second         : 30
microsecond    : 495051

Как и в случае с date , datetime предоставляет удобные методы класса для создания новых экземпляров. Он также включает fromordinal () и fromtimestamp () .

datetime_datetime_combine.py

import datetime

t  datetime.time(1, 2, 3)
print('t :', t)

d  datetime.date.today()
print('d :', d)

dt  datetime.datetime.combine(d, t)
print('dt:', dt)

comb () создает экземпляры datetime из одного экземпляра date и одного экземпляра time .

$ python3 datetime_datetime_combine.py

t : 01:02:03
d : 2018-12-09
dt: 2018-12-09 01:02:03

Форматирование и анализ

Строковое представление объекта datetime по умолчанию использует формат ISO-8601 ( ГГГГ-ММ-ДДТЧЧ: ММ: СС.мммммм ). Альтернативные форматы можно создать с помощью strftime () .

datetime_datetime_strptime.py

import datetime

format  "%a %b %d %H:%M:%S %Y"

today  datetime.datetime.today()
print('ISO     :', today)

s  today.strftime(format)
print('strftime:', s)

d  datetime.datetime.strptime(s, format)
print('strptime:', d.strftime(format))

Используйте datetime.strptime () для преобразования форматированных строк в экземпляры datetime .

$ python3 datetime_datetime_strptime.py

ISO     : 2018-12-09 10:46:30.598115
strftime: Sun Dec 09 10:46:30 2018
strptime: Sun Dec 09 10:46:30 2018

Те же коды форматирования можно использовать с мини-языком форматирования строк Python, поместив их после < code>: в спецификации поля строки формата.

datetime_format.py

import datetime

today  datetime.datetime.today()
print('ISO     :', today)
print('format(): {:%a %b %d %H:%M:%S %Y}'.format(today))

Каждый код формата datetime должен по-прежнему иметь префикс % , а последующие двоеточия рассматриваются как буквальные символы для включения в вывод.

$ python3 datetime_format.py

ISO     : 2018-12-09 10:46:30.659964
format(): Sun Dec 09 10:46:30 2018

В следующей таблице показаны все коды форматирования для 17:00 13 января 2016 г. в часовом поясе США и Востока.

коды формата strptime/strftime

Символ

Смысл

Пример

% a

Сокращенное название дня недели

‘Мы бы’

% А

Полное название дня недели

‘Среда’

% w

Номер дня недели – от 0 (воскресенье) до 6 (суббота)

‘3’

% d

День месяца (с нулями)

’13’

% b

Сокращенное название месяца

“Ян”

% B

Полное название месяца

‘Январь’

% m

Месяц в году

’01’

% y

Год без века

’16’

% Y

Год с веком

‘2016’

%ЧАС

Час в 24-часовом формате

’17’

Час из 12-часового формата

’05’

%п

ДО ПОЛУДНЯ ПОСЛЕ ПОЛУДНЯ

‘ВЕЧЕРА’

% M

Минуты

’00’

% S

Секунды

’00’

% f

Микросекунды

“000000”

% z

Смещение UTC для объектов с учетом часовых поясов

‘-0500’

% Z

Название часового пояса

‘СТАНДАРТНОЕ ВОСТОЧНОЕ ВРЕМЯ’

% j

День года

‘013’

% W

Неделя года

’02’

% c

Представление даты и времени для текущего языкового стандарта

‘Мы бы

Янв

13

17:00:00

2016 ‘

%Икс

Представление даты для текущего языкового стандарта

’01/13/16′

%ИКС

Представление времени для текущего языкового стандарта

’17: 00: 00 ‘

%%

Буквальный

персонаж

‘%’

Часовые пояса

В datetime часовые пояса представлены подклассами tzinfo . Поскольку tzinfo является абстрактным базовым классом, приложениям необходимо определить подкласс и предоставить соответствующие реализации для нескольких методов, чтобы сделать его полезным.

datetime включает в себя несколько наивную реализацию в классе timezone , которая использует фиксированное смещение от UTC и не поддерживает разные значения смещения в разные дни года, например, где применяется летнее время или когда смещение от UTC со временем менялось.

datetime_timezone.py

import datetime

min6  datetime.timezone(datetime.timedelta(hours6))
plus6  datetime.timezone(datetime.timedelta(hours6))
d  datetime.datetime.now(min6)

print(min6, ':', d)
print(datetime.timezone.utc, ':',
      d.astimezone(datetime.timezone.utc))
print(plus6, ':', d.astimezone(plus6))

# convert to the current system timezone
d_system  d.astimezone()
print(d_system.tzinfo, '      :', d_system)

Чтобы преобразовать значение datetime из одного часового пояса в другой, используйте astimezone () . В приведенном выше примере показаны два отдельных часовых пояса, по 6 часов по обе стороны от UTC, и экземпляр utc из datetime.timezone также используется для справки. Последняя строка вывода показывает значение в системном часовом поясе, полученное путем вызова astimezone () без аргументов.

$ python3 datetime_timezone.py

UTC-06:00 : 2018-12-09 09:46:30.709455-06:00
UTC : 2018-12-09 15:46:30.709455+00:00
UTC+06:00 : 2018-12-09 21:46:30.709455+06:00
EST       : 2018-12-09 10:46:30.709455-05:00

Примечание

Сторонний модуль pytz – лучшая реализация для часовых поясов. Он поддерживает именованные часовые пояса, а база данных смещений постоянно обновляется по мере того, как политические органы по всему миру вносят изменения.

Смотрите также