Нашли ошибку?
среднийNumPy 2.5.3

Даты: datetime64

Массивы дат и промежутков времени — арифметика, диапазоны, рабочие дни.

Нужно знать:Типы данных и astypeАрифметика с массивами

Содержание статьи

Коротко

  • datetime64 — момент времени, timedelta64 — промежуток. У обоих есть единица: D — дни, h — часы, m — минуты, s — секунды, M — месяцы, Y — годы.
  • Разница двух дат — timedelta64; дата плюс промежуток — дата.
  • np.arange(начало, конец, dtype="datetime64[D]") — все дни подряд.
  • astype("datetime64[M]") огрубляет дату до месяца, / np.timedelta64(1, "D") превращает промежуток в число дней.
  • Для анализа данных по датам обычно удобнее pandas: to_datetime и date_range.

Синтаксис

np.datetime64("2024-03-15")            # единица по строке: D
np.datetime64("2024-03-15T14:30")      # m — минуты
np.timedelta64(3, "D")
np.array(strings, dtype="datetime64[D]")
np.arange(start, stop, dtype="datetime64[D]")
np.busday_count(begin, end)

Примеры

Данные для примеровиспользуются во всех примерах ниже
start = np.datetime64("2024-02-27")      # начало проекта
deadline = np.datetime64("2024-03-31")   # срок сдачи
Создание дат
print(np.datetime64("2024-03-15"))
print(np.datetime64("2024-03-15T14:30"))
np.array(["2024-01-10", "2024-02-29"], dtype="datetime64[D]")
Вывод
2024-03-15
2024-03-15T14:30
array(['2024-01-10', '2024-02-29'], dtype='datetime64[D]')
Арифметика дат
print(start + np.timedelta64(3, "D"))              # високосный год: будет 1 марта
deadline - start                                   # разница — timedelta64
Вывод
2024-03-01
np.timedelta64(33,'D')
Все дни подряд
np.arange("2024-02-26", "2024-03-03", dtype="datetime64[D]")   # все дни подряд
Вывод
array(['2024-02-26', '2024-02-27', '2024-02-28', '2024-02-29',
       '2024-03-01', '2024-03-02'], dtype='datetime64[D]')
Смена единицы и разница в днях
d = np.datetime64("2024-03-15T14:30")
print(d.astype("datetime64[D]"))                   # отбросить время
print(d.astype("datetime64[M]"))                   # до месяца
(deadline - start) / np.timedelta64(1, "D")        # разница в днях числом
Вывод
2024-03-15
2024-03
np.float64(33.0)
Рабочие дни
print(np.is_busday(np.datetime64("2024-03-16")))   # суббота
np.busday_count("2024-03-01", "2024-04-01")        # рабочих дней в марте
Вывод
False
np.int64(21)

Подводные камни

Месяц нельзя прибавить к дате с днями

Длина месяца не фиксирована, поэтому промежутки в месяцах и годах не складываются с датами в днях. Для «плюс один месяц» используйте pd.DateOffset(months=1) в pandas.

Дата + 1 месяцошибка: TypeError
np.datetime64("2024-01-31") + np.timedelta64(1, "M")   # месяцы разной длины
Ошибка
UFuncTypeError: Cannot cast ufunc 'add' input 1 from dtype('<m8[M]') to dtype('<m8[D]') with casting rule 'same_kind'

timedelta64 без единицы устарел

Промежуток без единицыустаревший API
np.timedelta64(5)                                  # без единицы измерения
Вывод
DeprecationWarning: The 'generic' unit for NumPy timedelta is deprecated, and will raise an error in the future. This includes implicit conversion of bare integers (e.g. `+ 1`). Please use a specific unit instead.
np.timedelta64(5)