Почему одинаковые даты и время не равны?

Я работаю над простым скриптом Python3, который обрабатывает данные с шагом в пять минут. Благодаря этому посту у меня есть код, который берет любой объект даты и времени Python, а затем округляет его до ближайших пяти минут. (: 00, : 05, : 10, : 15 и т. д.) Обратите внимание, что я не могу использовать панд.

Теперь мне нужно иметь возможность сравнить это «округленное» время и дату с другими датами, и здесь я столкнулся с проблемой. Рассмотрим этот тестовый код:

import sys
from datetime import datetime
from datetime import timedelta

def roundDownDateTime(dt):
    # Arguments:
    #   dt      datetime object
    delta = timedelta(minutes=1) * (dt.minute % 5)
    return dt - delta

def testAlarm(testDate):
    # Arguments:
    #   testDate    datetime object
    currDate = roundDownDateTime( datetime.now() )      # currDate is a DateTime object, rounded down to 5 mins
    print("currDate:  "+currDate.strftime("%Y%m%d%H%M"))
    print("testDate:  "+testDate.strftime("%Y%m%d%H%M"))
    if (currDate == testDate):
        print("ALARM!!!!")

def main():
    testDate = datetime.strptime(sys.argv[1], "%Y%m%d%H%M")
    testAlarm(testDate)

if __name__ == "__main__":
    main()

Код делает все следующее:

  • Функция main() принимает строку, которую вы вводите в командной строке, затем преобразует его в "%Y%m%d%H%M" datetime
  • Дата и время округляются до последних пяти минут.
  • В testAlarm() ваша дата сравнивается с текущей датой, также в "%Y%m%d%H%M", также с округлением до пяти минут в меньшую сторону.
  • Если текущая дата соответствует аргументу строки cmd, вы должны получить "ALARM!!! в выводе.

Вот фактический результат, запущенный на моем компьютере с Ubuntu:

me@unbuntu1$ date
Tue Jan 17 14:27:41 UTC 2023
me@unbuntu1$ 
me@unbuntu1$ python3 toy04.py 202301171425
currDate:  202301171425
testDate:  202301171425
me@unbuntu1$

Хорошо: хотя я округляю свою дату в меньшую сторону, чтобы она соответствовала «округленной» версии текущей даты, строка кода if (currDate == testDate): по-прежнему оценивается как False. Хотя обе даты и времени выглядят равными в формате "%Y%m%d%H%M", они каким-то образом не равны.

Моя первая мысль заключалась в том, что, возможно, «округленная» дата-время все еще сохраняет некоторые остаточные секунды или микросекунды даже после части округления? Поэтому я изменил свою функцию на это:

def roundDownDateTime(dt):
    # Arguments:
    #   dt      DateTime object
    delta = timedelta(minutes=1) * (dt.minute % 5)
    dt = dt - delta
    dt.replace(second=0, microsecond=0)
    return dt

Но это не имеет значения; Я все еще получаю тот же результат, что и раньше.

Обычно вас волнует только currDate > testDate в тревожных целях. Но в моем случае я должен иметь возможность сравнивать дату и время на равенство после того, как один (или несколько) из них прошел через функцию roundDownDateTime(). Что мне не хватает? Моя функция roundDownDateTime() неисправна? Спасибо.

Скорее всего это ошибка округления с плавающей запятой

mousetail 17.01.2023 15:57
docs.python.org/3/library/datetime.html#datetime-objects — проверьте, не наивен ли один из них. Согласно документам: «Для сравнения на равенство наивные экземпляры никогда не равны осведомленным экземплярам».
matszwecja 17.01.2023 15:59

Вы печатаете strftime, но сравниваете объект даты и времени для currDate, которые не равны из-за десятичных знаков.

It_is_Chris 17.01.2023 16:02

@It_is_Chris Это отличный момент, вероятно, источник моего замешательства. Интересно, какой рекомендуемый способ печати даты и времени?

Pete 17.01.2023 16:09
Почему в Python есть оператор "pass"?
Почему в Python есть оператор "pass"?
Оператор pass в Python - это простая концепция, которую могут быстро освоить даже новички без опыта программирования.
Некоторые методы, о которых вы не знали, что они существуют в Python
Некоторые методы, о которых вы не знали, что они существуют в Python
Python - самый известный и самый простой в изучении язык в наши дни. Имея широкий спектр применения в области машинного обучения, Data Science,...
Основы Python Часть I
Основы Python Часть I
Вы когда-нибудь задумывались, почему в программах на Python вы видите приведенный ниже код?
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
Алиса и Боб имеют неориентированный граф из n узлов и трех типов ребер:
Оптимизация кода с помощью тернарного оператора Python
Оптимизация кода с помощью тернарного оператора Python
И последнее, что мы хотели бы показать вам, прежде чем двигаться дальше, это
Советы по эффективной веб-разработке с помощью Python
Советы по эффективной веб-разработке с помощью Python
Как веб-разработчик, Python может стать мощным инструментом для создания эффективных и масштабируемых веб-приложений.
0
4
53
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

dt.replace возвращает новый datetime объект; он не изменяется dt на месте.

def roundDownDateTime(dt):
    # Arguments:
    #   dt      DateTime object
    delta = timedelta(minutes=1) * (dt.minute % 5)
    dt = dt - delta
    return dt.replace(second=0, microsecond=0)

Другие вопросы по теме

Как стереть текст из .txt в python или AHK?
Определите и замените с помощью регулярного выражения некоторые строки, хранящиеся в списке, в строке, которая может их содержать или не содержать
Как записать время выполнения кода для нескольких функций в виде кадра данных pandas в Python
Дублирование списка с добавлением при каждом щелчке по флажку. Как я могу избежать дублирования?
Уменьшить размер авторизации Python AWS Lambda@Edge
Как я могу многократно генерировать новое случайное значение в списке в Python 3, пока все значения не будут выбраны случайным образом (один раз)
Как я могу решить «AttributeError: у объекта NoneType нет автора атрибута» и изменить NoneType, чтобы мой код мог работать правильно?
Apt-get install Python3 в новом образе Ubuntu Docker приводит к ошибке 13 Отказано в доступе
Mypy: ошибка: модуль «multiprocessing.managers» не имеет атрибута «EventProxy» [attr-defined]
Печать всех имен членов класса enum