4

I have the following two date/time which are date_time1 and date_time2 respectively:

2017-04-15 00:00:00
2017-04-17 15:35:19+00:00

parsed1 = dateutil.parser.parse(date_time1)
parsed2 = dateutil.parser.parse(date_time2)

and would if I were to receive another date/time called input_date_time (e.g. 2017-04-16 12:11:42+00:00), would like to do the following:

#    Would like to check if `input_date_time` is within the range 
if parsed1 <= input_date_time <= parsed2:
… 

And got an error: TypeError: can't compare offset-naive and offset-aware datetimes

Thought up of breaking it down to just year, month, day, hour, minute, and second, and compare every single one.

What would be the proper way to do so?

user513951
  • 12,445
  • 7
  • 65
  • 82
Jo Ko
  • 7,225
  • 15
  • 62
  • 120
  • Did you try your suggested code? Did it work? What errors do you get? – Daniel Roseman Apr 18 '17 at 22:50
  • 2
    Possible duplicate of [Can't compare naive and aware datetime.now() <= challenge.datetime\_end](http://stackoverflow.com/questions/15307623/cant-compare-naive-and-aware-datetime-now-challenge-datetime-end) – miradulo Apr 18 '17 at 22:55
  • @DanielRoseman Got `TypeError: can't compare offset-naive and offset-aware datetimes` – Jo Ko Apr 18 '17 at 23:04
  • The problem is that one of these has a timezone and the other one doesn't. If you want to assume they are in the same zone, just set the time zone of the aware one to `None`. – Paul Apr 18 '17 at 23:20
  • @Paul How can I do so? `input_date_time` is the aware it seems with local timezone. How can turn `parsed1` and `parsed2` aware? – Jo Ko Apr 18 '17 at 23:23

3 Answers3

7

here is my edited (again) example I think we should provide timezone data to every datetime object assume that date_time1 is a local time. I think we should add timezone data to date_time1 instead of clear other tzinfo (my first example)

import dateutil.parser
import datetime
from pytz import utc

date_time1 ='2017-04-15 00:00:00'
date_time2 ='2017-04-17 15:35:19+00:00'
input_date_time = '2017-04-16 12:11:42+00:00'

parsed1 = dateutil.parser.parse(date_time1).astimezone(utc)
parsed2 = dateutil.parser.parse(date_time2)
input_parsed = dateutil.parser.parse(input_date_time)

if parsed1 <= input_parsed  <= parsed2: 
    print('input is between')

this can check if input is between parsed1 and parsed2

Peter
  • 99
  • 5
  • 1
    This doesn't convert the times, it just removes the information. The comparison will then be incorrect. – OrangeDog Nov 28 '17 at 13:22
  • You can just `from pytz import utc`. Are you sure `localize` does the correct thing here? – OrangeDog Jul 17 '18 at 12:59
  • OK, I just fixed it. Assume that date_time1 is a local time. This will be better than the previous one. – Peter Jul 18 '18 at 07:14
1

Assuming you have python datetime obejcts, two objects in python can be compared with the "<", "==", and ">" signs.

You don't need to parse them to compare them.

if date_time1 <= input_date_time <= datetime_2:
    #do work

If you don't have datetime objects, there is also a method called datetime in the datetime class, which will allow you to create datetime objects, if you'll find that useful.

  • Getting the following error: `TypeError: can't compare offset-naive and offset-aware datetimes` – Jo Ko Apr 18 '17 at 23:08
1

You need to apply a timezone to the 'naive ' datetime object (2017-04-15 00:00:00 in your example) (to make it TZ aware) OR convert the 'aware' datetime object (2017-04-17 15:35:19+00:00 in your example) to a 'naive' object and the date you are trying to compare. Then your TypeError will disappear.

Since your second date has a timezone offset of +00:00 and your input_datetime is also +00:00, let's apply UTC to the naive first date (assuming that it's the correct timezone) and then convert it to whatever timezone you need (you can skip the conversion if UTC is correct - the comparison will now work.)

parsed1 = dateutil.parser.parse(date_time1)
parsed2 = dateutil.parser.parse(date_time2)
# make parsed1 timezone aware (UTC)
parsed1 = parsed1.replace(tzinfo=pytz.utc)

Now your comparison should work. If you want to apply another timezone to any of the dates, you can use the astimezone function. Lets change the timezone to that applicable to Sydney, Australia. Here is a list of timezones https://gist.github.com/heyalexej/8bf688fd67d7199be4a1682b3eec7568

syd_tz = pytz.timezone('Australia/Sydney')
syd_parsed1 = parsed1.astimezone(syd_tz)

You can now check what timezone is applied to each of your datetime objects using the %zand %Z parameters for strftime. Using %c will print it in the local time format as will %x and %X. Using Python3+:

print("Local time: %s" % syd_parsed1.strftime('%c'))
print("Offset-Timezone-Date-Time: %s" % syd_parsed1.strftime("%z-%Z-%x-%X))

Hope that helps, the timezone functions did my head in when I used them the first time when I didn't know about %c.

tnd
  • 21
  • 1