Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to filter models using timezone aware dates?

So I am trying to filter django models by date. Using either only the year, year+month, or year+month+day_of_month. The strategy I am using now is this:

n.filter(create_date__year=q)
n.filter(create_date__year=q[:4],create_date__month=q[4:6])
n.filter(create_date__year=q[:4],create_date__month=q[4:6],create_date__day=q[6:8])

Where 'q' is a date string in the format of either either 'yyyy', 'yyyymm' or 'yyyymmdd' respectively.

This is working pretty well but django is not taking into account timezone. Django searches based on the UTC times and not the EDT, which is what the actual datetime object is set to.

Is there a way to search the year/month/day of month based on a specific timezone?

like image 327
user439299 Avatar asked Oct 03 '13 15:10

user439299


People also ask

How do you make a datetime object timezone aware?

Timezone aware object using pytz You can also use the pytz module to create timezone-aware objects. For this, we will store the current date and time in a new variable using the datetime. now() function of datetime module and then we will add the timezone using timezone function of pytz module.

How do I make my timezone aware?

To make them timezone-aware, you must attach a tzinfo object, which provides the UTC offset and timezone abbreviation as a function of date and time. For zones with daylight savings time, python standard libraries do not provide a standard class, so it is necessary to use a third party library.

What is TZ aware?

Localize tz-naive DatetimeIndex to tz-aware DatetimeIndex. This method takes a time zone (tz) naive DatetimeIndex object and makes this time zone aware. It does not move the time to another time zone. Time zone localization helps to switch from time zone aware to time zone unaware objects.

Is datetime now offset aware?

So a datetime object can be either offset naive or offset aware. A timezone's offset refers to how many hours the timezone is from Coordinated Universal Time (UTC). A naive datetime object contains no timezone information.


2 Answers

Yes, when support for time zones is enabled, Django stores date and time information in UTC in the database, uses time-zone-aware datetime objects internally, and translates them to the end user’s time zone in templates and forms.

Set USE_TZ = True in your settings file.

Create a time-zone-aware datetime first convert it to utc and use that in your filter.

>>> import datetime
>>> import pytz
>>> 
>>> unaware = datetime.datetime.strptime("20131103", "%Y%m%d")
>>> amsterdam = pytz.timezone('Europe/Amsterdam')
>>> aware = unaware.replace(tzinfo=amsterdam)
>>> d = aware.astimezone(pytz.UTC)
>>> 
>>> unaware
datetime.datetime(2013, 11, 3, 0, 0)
>>> amsterdam
<DstTzInfo 'Europe/Amsterdam' AMT+0:20:00 STD>
>>> aware
datetime.datetime(2013, 11, 3, 0, 0, tzinfo=<DstTzInfo 'Europe/Amsterdam' AMT+0:20:00 STD>)
>>> d
datetime.datetime(2013, 11, 2, 23, 40, tzinfo=<UTC>)
>>> 

Now you can filter your objects with d.

objs = SomeModel.objects.all() 

objs.filter(date__year=d.year)
objs.filter(date__year=d.year, date_month=d.month)
objs.filter(date=d.date)
like image 80
allcaps Avatar answered Sep 28 '22 06:09

allcaps


To get the current day in a given timezone, I use the following utils function which might be useful in your case called with the pytz.timezone("America/New_York") argument.

from django.utils.timezone import now

def timezone_today(tz=utc):
    """
    Return the current date in the given timezone :param:`tz`.
    """
    return now().astimezone(tz).date()
like image 27
sebastibe Avatar answered Sep 28 '22 05:09

sebastibe