【问题标题】:Weird Python Date Comparison Behaviour奇怪的 Python 日期比较行为
【发布时间】:2018-12-25 21:43:36
【问题描述】:

我遇到了奇怪的 Python 日期时间比较问题。我得到两个字符串格式的日期时间(来自 REST 调用,JSON)开始日期时间和结束日期时间。我必须比较当前日期时间,如果它在这个范围内(开始日期时间和结束日期时间)采取一些行动。众所周知,这些日期的时区是美国/东部(美国北卡罗来纳州)。这是代码,

from pytz import timezone
from datetime import datetime

def main():

    # All the dates are in US/Eastern time zone. Time zone for USA, North Carolina
    # These dates are received from REST call in JSON
    # I need to compare the current date time, if that falls within this range take some action

    start_date_str = "7/17/2018 11:30:00 AM"
    end_date_str = "7/17/2018 2:30:00 PM"

    # To simulate current date time within the range, I will update the current date time value.
    current_est_time = datetime.now(tz=timezone('US/Eastern'))
    current_est_time = current_est_time.replace(year=2018, month=7, day=17, hour=12, minute=26)
    print current_est_time

    start_date = datetime.strptime(start_date_str,"%m/%d/%Y %I:%M:%S %p").replace(tzinfo=timezone('US/Eastern'))
    end_date = datetime.strptime(end_date_str, "%m/%d/%Y %I:%M:%S %p").replace(tzinfo=timezone('US/Eastern'))

    print start_date <= current_est_time <= end_date


if __name__ == '__main__':
    main()

如果分钟值为 26,则比较打印 True,如果是 25,则打印 False。

上述代码示例的输出是

2018-07-17 12:26:06.646643-04:00
 True


如果将 current_est_time 变量的分钟值更改为 25,则输出为
2018-07-17 12:25:16.582573-04:00
False

有人可以帮我吗,我哪里出错了?

【问题讨论】:

  • 您能提供您最近一次参加的考试吗?带输入/输出。
  • 上述代码示例的输出为 2018-07-17 12:27:34.806142-04:00 True。如果将 current_est_time 变量的分钟值更改为 25,则输出为 2018-07-17 12:25:16.582573-04:00 False
  • 代码对你有用吗???
  • 嗨 Inder,请查看我的最新回答。

标签: python python-2.7 python-2.x python-datetime pytz


【解决方案1】:

进一步调试此问题后,.replace 方法如何处理 datetime 对象的时区信息似乎存在问题。如果我们使用 .replace 方法添加时区,则 start_date 中的 tzinfo 对象有 _tzname = "LMT",而 current_est_time 中的 tzinfo 对象有 _tzname = "EDT"。这就是比较结果不一致的原因。
通过引用Why doesn't pytz localize() produce a datetime object with tzinfo matching the tz object that localized it?
,看起来“EDT”是正确的值。所以我认为这是实现这一点的正确方法,

from datetime import datetime
import pytz

def main():
    process_date_time(25)
    process_date_time(26)

def process_date_time(min):
    # All the dates are in US/Eastern time zone. Time zone for USA, North Carolina
    # These dates are received from REST call in JSON
    # I need to compare the current date time, if that falls within this range take some action
    tz = pytz.timezone('US/Eastern')
    start_date_str = "7/17/2018 11:30:00 AM"
    end_date_str = "7/17/2018 2:30:00 PM"

    # To simulate current date time within the range, I will update the current date time value.
    dt = datetime.now()
    current_est_time = tz.localize(dt)
    current_est_time = current_est_time.replace(year=2018, month=7, day=17, hour=12, minute=min)
    print current_est_time

    start_date_1 = datetime.strptime(start_date_str, "%m/%d/%Y %I:%M:%S %p")
    end_date_1 = datetime.strptime(end_date_str, "%m/%d/%Y %I:%M:%S %p")

    start_date = tz.localize(start_date_1)
    end_date = tz.localize(end_date_1)

    print start_date <= current_est_time <= end_date


if __name__ == '__main__':
    main()

【讨论】:

    【解决方案2】:

    错误是由不同的偏移量 datetime.now() 调用引起的,它返回:

    2018-07-17 12:26:06.646643-04:00
    

    但是,您的日期比较与比较之前的结构不同:

    2018-07-17 14:30:00-04:56
    

    两个值的偏移量不同,当前的 4:00 和开始和结束日期的 4:56

    以下代码将修复它:

    from pytz import timezone
    from datetime import datetime
    
    def main():
    
        # All the dates are in US/Eastern time zone. Time zone for USA, North Carolina
        # These dates are received from REST call in JSON
        # I need to compare the current date time, if that falls within this range take some action
    
        start_date_str = "7/17/2018 11:30:00 AM"
        end_date_str = "7/17/2018 2:30:00 PM"
    
        # To simulate current date time within the range, I will update the current date time value.
        current_est_time = datetime.now(tz=timezone('US/Eastern'))
        current_est_time = current_est_time.replace(year=2018, month=7, day=17, hour=12, minute=24).replace(tzinfo=timezone("US/Eastern"))
        print (current_est_time)
    
        start_date = datetime.strptime(start_date_str,"%m/%d/%Y %I:%M:%S %p").replace(tzinfo=timezone('US/Eastern'))
        end_date = datetime.strptime(end_date_str, "%m/%d/%Y %I:%M:%S %p").replace(tzinfo=timezone('US/Eastern'))
        print(start_date)
        print(current_est_time)
        print(end_date)
        print (start_date <= current_est_time <= end_date)
    
    
    if __name__ == '__main__':
        main()
    

    附:它是用 python3 编写的,但应该可以正常工作

    【讨论】:

    • 感谢您对 Inder 的评论!但我不认为毫秒是这里的问题。如果您只是将 microsecond=0 添加到 current_est_time.replace,它会删除微/毫秒值,但问题仍然存在。您的代码有效,因为您还删除了时区信息。这样做的简单方法是只写 current_est_time = current_est_time.replace(tzinfo=None) 并且不要在代码的后面部分使用任何时区信息。现在我要解决这个问题(删除时区信息)。
    • @SaurabhDeshpande 为之前的错误感到抱歉
    猜你喜欢
    • 1970-01-01
    • 2014-08-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-11-24
    • 1970-01-01
    相关资源
    最近更新 更多