奇怪的Python日期比较行为

时间:2018-07-18 05:19:02

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

我面临着奇怪的Python日期时间比较问题。我得到两个日期时间的字符串格式(从REST Call,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

有人可以帮助我,我在哪里错了?

2 个答案:

答案 0 :(得分:0)

该错误是由另一个偏移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()

P.S。它是用python3编写的,但应该可以正常工作

答案 1 :(得分:0)

进一步调试此问题后,.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()