2

I am facing weird Python Date Time Comparison issue. I am getting two date times in string format (From REST Call, JSON) start date time and end date time. I have to compare current date time and if it falls within this rage (start date time and end date time) take some action. It is known that the time zone of these dates is US/Eastern (USA North Carolina). Here is the code,

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()

If minute value is 26, comparison prints True, if it is 25, it prints False.

Output of the above code sample is

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


If you change the minute value for current_est_time variable to 25, output is
2018-07-17 12:25:16.582573-04:00
False

Can somebody please help me, where I am going wrong here ?

Tom Zych
  • 13,329
  • 9
  • 36
  • 53

2 Answers2

0

The error is being caused by a different offset datetime.now() call, which returns:

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

however your date comparisons don't have the similar structure they just before comparison will look like this:

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

the offset is different in both the values, for current its 4:00 and for start and end date its 4:56

The following code will fix it:

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. its written in python3 but should work just fine

Inder
  • 3,711
  • 9
  • 27
  • 42
  • Thanks for your comment Inder ! But I don't think millisecond is an issue here. If you just add microsecond=0 to the current_est_time.replace, it gets rid of the micro/millisecond values but the issue persists. Your code works because, you also have removed timezone information. Simple way doing so is to just write current_est_time = current_est_time.replace(tzinfo=None) and do not use any timezone info in later part of the code. For now I am going with this (removing time zone info) work around. – Saurabh Deshpande Jul 18 '18 at 09:24
  • @SaurabhDeshpande found it sorry for the earlier mistake – Inder Jul 18 '18 at 09:51
0

After debugging this issue further, there seems to be an issue with how .replace method handles timezone information to the datetime object. If we use .replace method to add timezone, tzinfo object in the start_date has _tzname = "LMT" and tzinfo object in the current_est_time has _tzname = "EDT". And that's why comparison result is not consistent.
By referring to Why doesn't pytz localize() produce a datetime object with tzinfo matching the tz object that localized it?
,it looks like "EDT" is the correct value. So In my opinion here is the correct way of implementing this,

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()