2

I'm working on a django project and i got confused about the timezones.

I have a campaing object, it has publish_start and publish_end dates.

example output from the console;

campaingObject.publish_start
datetime.datetime(2015, 9, 1, 0, 0)

campaingObject.publish_end
datetime.datetime(2015, 9, 28, 10, 10)

I want to get campaing objects that are active now. That means publish start is less then current time, end time is greater then current time.

When i call:

datetime.now()
datetime.datetime(2015, 9, 28, 5, 42, 37, 448415)

This result is not in my timezone. I can get my own time info with

datetime.now(pytz.timezone('Europe/Istanbul'))

but this time i can not compare values to find which objects are active right now.

datetime.now(pytz.timezone('Europe/Istanbul')) > campaingObject.publish_end
TypeError: can't compare offset-naive and offset-aware datetimes

How can i compare this times to find which objects are active right now?

Sefa
  • 8,865
  • 10
  • 51
  • 82

2 Answers2

3

You can use the make_aware function from django on your naive datetime objects. You will then have to specify the time zone of your naive timestamps.

now_ts = datetime.now(pytz.timezone('Europe/Istanbul'))
now_ts > make_aware(campaingObject.publish_end, pytz.timezone('Europe/Istanbul'))

https://docs.djangoproject.com/en/1.8/ref/utils/#django.utils.timezone.make_aware

On the other hand, you could also use the make_naive function to remove the timezone information from your now() timestamp:

now_ts = datetime.now(pytz.timezone('Europe/Istanbul'))
now_naive = make_naive(now_ts, pytz.timezone('Europe/Istanbul'))
now_naive > campaingObject.publish_end

https://docs.djangoproject.com/en/1.8/ref/utils/#django.utils.timezone.make_naive

Tim
  • 1,272
  • 11
  • 28
1
   datetime.now(pytz.timezone('Europe/Istanbul')) > campaingObject.publish_end
   TypeError: can't compare offset-naive and offset-aware datetimes

How can i compare this times to find which objects are active right now?

Use timezone-aware datetime objects everywhere. If USE_TZ = True then django uses timezone-aware datetime objects internally. In particular, timezone.now() returns an aware datetime object.

timezone.localtime(timezone.now()) returns the current time in the current time zone -- you don't need to call timezone.localtime() explicitly -- the current time zone is used for rendering automatically. You could use activate('Europe/Istanbul') to change the current time zone if the default time zone TIME_ZONE is not suitable for the request.

How to make a time object TZ aware without changing the value?

If you've configured USE_TZ=True; you shouldn't see naive datetime objects. To attach the current time zone to a naive datetime object, call dt = timezone.make_aware(naive_dt).

In general, you could call pytz_timezone.localize() method directly:

#!/usr/bin/env python
from datetime import datetime
import pytz

tz = pytz.timezone('Europe/Istanbul')
now = datetime.now(tz) # get the current time
then = tz.localize(datetime.strptime('2015-09-15 17:05', '%Y-%m-%d %H:%M'),
                   is_dst=None)

Here're more details about what is is_dst flag and why do you need it, see "Can I just always set is_dst=True?" section.

Community
  • 1
  • 1
jfs
  • 399,953
  • 195
  • 994
  • 1,670