Mars J
Mars J

Reputation: 922

timezone aware vs. timezone naive in python

I am working with datetime objects in python. I have a function that takes a time and finds the different between that time and now.

def function(past_time):
    now = datetime.now()
    diff = now - past_time

When I initialized past_time before passing it to this function I initialized it as datetime naive. And now is also a datetime naive object. However when I try to call this function I get the error: can't subtract offset-naive and offset-aware datetimes. How come this is the case if they are both theoretically datetime naive objects?

Any help would be appreciated. Thanks!

Upvotes: 8

Views: 14482

Answers (3)

Luke West
Luke West

Reputation: 15013

I ran into this post and wanted to give you an alternative answer (I know it was originally posted in 2016!)

I have a UTC aware date on an object (in my case an RDS snapshot). I needed to compare this with a naive variable.

I want to process snapshots older than days_ago days old for the supplied current_date, time=00:01, and timezone=+00:00

e.g. If... current_date is 2023-11-08 11:10:04.123456 days_ago is 30 I want the cut_off_date to be 2023-10-11 00:01:00.000000+00:00

Here are the steps:

  1. Create a UTC aware variable cut_off_date
  2. Create a timezone variable utc_tzinfo which has an offset of 0 hours
  3. Set cut_off_date to be the supplied date - 30 days
  4. Set the time to 00:01
  5. Set the timezone to be utc_tzinfo
        # Calculate the cutoff date for deleting backups.
        # this needs to be UTC aware, so has to have a timezone. Which is UTC or +00:00
        utc_offset = datetime.timedelta(hours=0)
        utc_tzinfo = datetime.timezone(utc_offset)

        # create cut off date, for 00:01 in the morning, and timezone of UTC
        cut_off_date = current_date - datetime.timedelta(days=days_ago)
        cut_off_date = cut_off_date.replace(hour=19, minute=1, second=0, microsecond=0)
        cut_off_date = cut_off_date.replace(tzinfo=utc_tzinfo)

        # now you can compare a TZ aware variable with your chosen time

Upvotes: 0

yasir
yasir

Reputation: 13

Use :

    now = now.replace(tzinfo=past_time.tzinfo)

before diff = now - past_time.

so that both now and past_time have same tzinfo.

only if now and past_time intended to be in same timezone.

Upvotes: 1

nOw2
nOw2

Reputation: 666

datetime doesn't do any cross time zone calculations, because it's a complex and involved subject.

I suggest converting dates to UTC universally and performing maths on those.

I recently completed a project using timezones in a large python/Django project and after investigation went with converting everything internally to UTC and converting only on display to the user.

You should look into pytz to do the conversions to/from UTC, and store Olson codes for the timezones you want in your app - perhaps associated with each user, or appropriate to your program.

Upvotes: 14

Related Questions