Python: Получить день недели из datetime (воскресенье как 0)
Узнайте, как получить день недели из объектов datetime в Python, считая воскресенье как 0. Используйте метод weekday() с простым преобразованием для точных результатов.
Как получить номер дня недели из объекта datetime в Python?
Мне нужно определить день недели для заданной даты, считая воскресенье первым днем (0), понедельник вторым (1) и так далее.
Например, если у меня есть объект datetime, представляющий 20 октября 2017 г. (это был пятница), я хочу получить значение 6.
Пример:
>>> today = datetime.datetime(2017, 10, 20)
>>> # Какой метод нужно вызвать, чтобы получить день недели?
>>> # Ожидаемый результат: 6 (для пятницы)
Какой метод следует вызвать у объекта datetime, чтобы получить день недели в виде целого числа?
Чтобы получить день недели из объекта datetime в Python, где воскресенье считается 0, а понедельник — 1, можно воспользоваться методом .weekday() и применить простую математическую трансформацию. Для 20 октября 2017 г. (пятница) правильный подход — (datetime.weekday() + 1) % 7, который вернёт 5 для пятницы.
Содержание
- Использование метода weekday()
- Понимание альтернативы isoweekday()
- Полный пример с 20 октября 2017
- Опции форматирования названий дней
- Распространённые случаи использования и примеры
- Проблемы производительности
Использование метода weekday()
Метод datetime.weekday() возвращает день недели как целое число, где понедельник = 0, а воскресенье = 6. Чтобы преобразовать это в систему, где воскресенье = 0, а понедельник = 1, необходимо применить простую трансформацию.
import datetime
# Получаем день недели (Понедельник=0, Воскресенье=6)
day_of_week = datetime.datetime.now().weekday()
# Преобразуем в систему Воскресенье=0, Понедельник=1
sunday_first_day = (day_of_week + 1) % 7
Формула (datetime.weekday() + 1) % 7 работает так:
- Прибавляем 1, чтобы сдвинуть понедельник с 0 на 1
- Используем модуль 7, чтобы обернуть воскресенье с 6 на 0
Это даёт точную карту, которую вам нужно:
- Понедельник:
(0 + 1) % 7 = 1 - Вторник:
(1 + 1) % 7 = 2 - Среда:
(2 + 1) % 7 = 3 - Четверг:
(3 + 1) % 7 = 4 - Пятница:
(4 + 1) % 7 = 5 - Суббота:
(5 + 1) % 7 = 6 - Воскресенье:
(6 + 1) % 7 = 0
Понимание альтернативы isoweekday()
Python также предоставляет метод isoweekday(), который возвращает день недели как целое число, где понедельник = 1, а воскресенье = 7. Это соответствует стандарту ISO 8601.
import datetime
# Используем isoweekday() (Понедельник=1, Воскресенье=7)
iso_day = datetime.datetime.now().isoweekday()
# Преобразуем в систему Воскресенье=0, Понедельник=1
sunday_first_day = (iso_day % 7)
Метод ISO даёт:
- Понедельник: 1 →
1 % 7 = 1 - Вторник: 2 →
2 % 7 = 2 - Среда: 3 →
3 % 7 = 3 - Четверг: 4 →
4 % 7 = 4 - Пятница: 5 →
5 % 7 = 5 - Суббота: 6 →
6 % 7 = 6 - Воскресенье: 7 →
7 % 7 = 0
Оба подхода дают одинаковый результат, но метод weekday() часто предпочтительнее, так как не требует дополнительной операции modulo.
Полный пример с 20 октября 2017
Реализуем полный пример для вашего конкретного случая:
import datetime
# Создаём объект datetime для 20 октября 2017
october_20_2017 = datetime.datetime(2017, 10, 20)
# Получаем день недели с помощью метода weekday()
day_of_week = october_20_2017.weekday()
print(f"weekday() result: {day_of_week}") # Вывод: 4 (Пятница)
# Преобразуем в систему Воскресенье=0, Понедельник=1
sunday_first_day = (day_of_week + 1) % 7
print(f"Sunday-first result: {sunday_first_day}") # Вывод: 5
20 октября 2017 действительно был пятницей, и с нашей формулой преобразования:
- Пятница (4) →
(4 + 1) % 7 = 5
Вот полная функция, которую можно использовать:
import datetime
def get_day_of_week_sunday_first(dt):
"""
Получить день недели как целое число с Воскресенье=0, Понедельник=1, ..., Суббота=6
Args:
dt: объект datetime
Returns:
int: День недели (0=Воскресенье, 1=Понедельник, ..., 6=Суббота)
"""
return (dt.weekday() + 1) % 7
# Примеры использования
today = datetime.datetime.now()
print(f"Today is day: {get_day_of_week_sunday_first(today)}")
october_20_2017 = datetime.datetime(2017, 10, 20)
print(f"Oct 20, 2017 is day: {get_day_of_week_sunday_first(october_20_2017)}")
Опции форматирования названий дней
Хотя вы просили целочисленное представление, часто полезно получить и название дня. Python предоставляет несколько способов форматирования названий дней:
import datetime
dt = datetime.datetime(2017, 10, 20) # Пятница
# Получаем название дня
day_name = dt.strftime("%A") # "Friday"
short_day = dt.strftime("%a") # "Fri"
# Получаем название дня из целого числа
weekdays = ["Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"]
day_name_from_int = weekdays[(dt.weekday() + 1) % 7] # "Friday"
# Пользовательское форматирование
custom_format = dt.strftime("Day %w: %A") # "Day 5: Friday"
Вот сравнение различных методов:
| Метод | Возвращает | Диапазон | Примечания |
|---|---|---|---|
weekday() |
Целое число | 0‑6 | Понедельник = 0, Воскресенье = 6 |
isoweekday() |
Целое число | 1‑7 | Понедельник = 1, Воскресенье = 7 |
strftime("%A") |
Строка | Полное название дня | |
strftime("%a") |
Строка | Сокращённое название дня | |
strftime("%w") |
Строка | Целое число | Воскресенье = 0, Суббота = 6 |
Распространённые случаи использования и примеры
1. Условная логика на основе дня недели
import datetime
def is_weekend(dt):
"""Проверить, является ли дата выходным"""
day = (dt.weekday() + 1) % 7 # Воскресенье=0, Суббота=6
return day == 0 or day == 6
# Использование
today = datetime.datetime.now()
if is_weekend(today):
print("Это выходной!")
else:
print("Это будний день")
2. Действия, зависящие от дня недели
import datetime
def get_weekday_action(dt):
"""Получить действие на основе дня недели"""
day = (dt.weekday() + 1) % 7
actions = {
0: "Отдых и релаксация", # Воскресенье
1: "Начать новые проекты", # Понедельник
2: "Командные встречи", # Вторник
3: "Промежуточный обзор", # Среда
4: "Презентации клиентам", # Четверг
5: "Завершение работы", # Пятница
6: "Подготовка к выходным" # Суббота
}
return actions[day]
# Пример использования
friday = datetime.datetime(2017, 10, 20)
print(f"Пятничное действие: {get_weekday_action(friday)}")
3. Анализ диапазона дат
import datetime
def count_weekdays(start_date, end_date):
"""Подсчитать будние и выходные дни в диапазоне дат"""
current = start_date
weekday_count = 0
weekend_count = 0
while current <= end_date:
day = (current.weekday() + 1) % 7
if day == 0 or day == 6:
weekend_count += 1
else:
weekday_count += 1
current += datetime.timedelta(days=1)
return weekday_count, weekend_count
# Использование
start = datetime.datetime(2017, 10, 1)
end = datetime.datetime(2017, 10, 31)
weekdays, weekends = count_weekdays(start, end)
print(f"Октябрь 2017: {weekdays} будних дней, {weekends} выходных дней")
Проблемы производительности
Для большинства приложений разница в производительности между этими методами незначительна. Однако для критичных к производительности участков кода стоит учитывать следующее:
import datetime
import timeit
# Сравнение производительности
setup = '''
import datetime
dt = datetime.datetime.now()
'''
# Тестируем разные методы
weekday_test = '''
day = (dt.weekday() + 1) % 7
'''
isoweekday_test = '''
day = (dt.isoweekday() % 7)
'''
strftime_test = '''
day = int(dt.strftime("%w"))
'''
# Запускаем бенчмарки
weekday_time = timeit.timeit(weekday_test, setup=setup, number=100000)
isoweekday_time = timeit.timeit(isoweekday_test, setup=setup, number=100000)
strftime_time = timeit.timeit(strftime_test, setup=setup, number=100000)
print(f"метод weekday(): {weekday_time:.6f} секунд")
print(f"метод isoweekday(): {isoweekday_time:.6f} секунд")
print(f"метод strftime(): {strftime_time:.6f} секунд")
Обычно .weekday() является самым быстрым вариантом, так как это простое чтение атрибута, тогда как strftime() включает парсинг строки и значительно медленнее.
Для повседневного использования я рекомендую подход .weekday() с трансформацией (weekday + 1) % 7, поскольку он и эффективен, и понятен.
Вывод
Чтобы получить день недели из объекта datetime в Python с воскресеньем как 0 и понедельником как 1, используйте метод .weekday() в сочетании с трансформацией (datetime.weekday() + 1) % 7. Этот подход даёт точную карту: Воскресенье = 0, Понедельник = 1, Вторник = 2, Среда = 3, Четверг = 4, Пятница = 5, Суббота = 6.
Ключевые выводы:
- Используйте
datetime.weekday()для максимальной производительности. - Применяйте
(weekday + 1) % 7, чтобы получить Воскресенье = 0, Понедельник = 1. - Для 20 октября 2017 (пятница) это возвращает 5, а не 6.
- Рассмотрите
isoweekday(), если вам нужен стандарт ISO 8601 (Понедельник = 1, Воскресенье = 7). - Используйте
strftime()для форматирования названий дней.
Этот метод надёжен, эффективен и работает одинаково во всех версиях Python, поддерживающих объекты datetime.