Другое

Python: Получить день недели из datetime (воскресенье как 0)

Узнайте, как получить день недели из объектов datetime в Python, считая воскресенье как 0. Используйте метод weekday() с простым преобразованием для точных результатов.

Как получить номер дня недели из объекта datetime в Python?

Мне нужно определить день недели для заданной даты, считая воскресенье первым днем (0), понедельник вторым (1) и так далее.

Например, если у меня есть объект datetime, представляющий 20 октября 2017 г. (это был пятница), я хочу получить значение 6.

Пример:

python
>>> today = datetime.datetime(2017, 10, 20)
>>> # Какой метод нужно вызвать, чтобы получить день недели?
>>> # Ожидаемый результат: 6 (для пятницы)

Какой метод следует вызвать у объекта datetime, чтобы получить день недели в виде целого числа?

Чтобы получить день недели из объекта datetime в Python, где воскресенье считается 0, а понедельник — 1, можно воспользоваться методом .weekday() и применить простую математическую трансформацию. Для 20 октября 2017 г. (пятница) правильный подход — (datetime.weekday() + 1) % 7, который вернёт 5 для пятницы.

Содержание

Использование метода weekday()

Метод datetime.weekday() возвращает день недели как целое число, где понедельник = 0, а воскресенье = 6. Чтобы преобразовать это в систему, где воскресенье = 0, а понедельник = 1, необходимо применить простую трансформацию.

python
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. Прибавляем 1, чтобы сдвинуть понедельник с 0 на 1
  2. Используем модуль 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.

python
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

Реализуем полный пример для вашего конкретного случая:

python
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

Вот полная функция, которую можно использовать:

python
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 предоставляет несколько способов форматирования названий дней:

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. Условная логика на основе дня недели

python
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. Действия, зависящие от дня недели

python
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. Анализ диапазона дат

python
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} выходных дней")

Проблемы производительности

Для большинства приложений разница в производительности между этими методами незначительна. Однако для критичных к производительности участков кода стоит учитывать следующее:

python
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.

Источники

  1. Документация Python datetime.weekday()
  2. Документация Python datetime.isoweekday()
  3. Коды форматирования strftime()
  4. Формат даты и времени ISO 8601
Авторы
Проверено модерацией
Модерация