Django ORM Syntax for 'LIKE' queries with respect to Datetime - python

I have this table which has column "date" in the format "2021-03-12 08:12:44.350176".
I want to compare a external date such as "2021-03-12 08:12:44"
I have tried this
new_date = datetime.datetime(2021, 3, 12, 8, 12, 44, tzinfo=<UTC>)
obj = Test.objects.filter(date__contains=new_date).all()
But it doesn't work, it returns empty sets.
My goal is to fetch all the records against the new_date.
Is there a way to remove milliseconds or way to compare the two dates?

It seems you want to compare datetimes upto the second while truncating the milliseconds. You can do that (and similar) by using either Trunc [Django docs] or one of it's subclasses. For truncating to the seconds you can use TruncSecond for your purpose:
import datetime
from django.db.models.functions import TruncSecond
from django.utils import timezone
new_date = datetime.datetime(2021, 3, 12, 8, 12, 44, tzinfo=timezone.utc)
obj = Test.objects.annotate(
trunc_date=TruncSecond(
'date',
tzinfo=timezone.utc
)
).filter(trunc_date=new_date)

according to [Django Docs]:
date
For datetime fields, casts the value as date. Allows chaining additional field lookups. Takes a date value.
date means a datetime.date object.
so you can use __date for datetime fields.

Related

Can Dates be Timezone-Aware in Python?

There's lots of SO answers on ensuring datetimes are a particular timezone. For example you can ensure your datetime is UTC with
from datetime import datetime
import pytz
now_utc = datetime.utcnow()
which yields:
datetime.datetime(2017, 5, 11, 17, 37, 5, 602054)
you can make that datetime aware of its timezone (e.g. for asserting two different datetime objects are from the same timezone) with
now_utc_aware = datetime.now(pytz.utc)
datetime.datetime(2017, 5, 11, 17, 38, 2, 757587, tzinfo=< UTC>)
But when I pull the date from a timezone-aware datetime, I seem to lose the timezone-awareness.
now_utc_aware.date()
datetime.date(2017, 5, 11)
Interestingly, there's a SO question which seems to ask exactly this, and about a date specifically (datetime.today()), but the answers (including an accepted one) relate to datetimes. The code I've seen to add timezone awareness to datetimes all seem to throw errors on my datetime.date object.
Is it possible to add timezone awareness to a date object?
From the Python docs:
class datetime.date
An idealized naive date, ... Attributes: year, month, and day.
There's nothing there for time or time zone. It's just a date.
While it is true that not everywhere on Earth is on the same date simultaneously (because of time zones), that doesn't mean a date itself has time zone awareness.
As a real-world analogy, think of a date as just a square on a calendar. One cannot start talking about timezones without introducing time, which is measured by a clock, not a calendar.

Why does the converting a dateutil rrule to a string and back make it lose its timezone information?

The dateutil.rrule module has an rrule class which has a custom __str__ method to convert its instances to strings, and a rrulestr function which does the opposite, namely, convert the string back to an object.
It seems, however, that the _dtstart attribute of the rrule loses its timezone information when converting to a string and back. For example, in the following script:
from dateutil.rrule import rrule, rrulestr, DAILY
from dateutil.parser import parse
start = parse("8 Feb 2017 14:00 UTC")
my_rrule = rrule(DAILY, dtstart=start)
my_rrule2 = rrulestr(str(my_rrule))
assert my_rrule._dtstart == my_rrule2._dtstart
the assertion leads to a
TypeError: can't compare offset-naive and offset-aware datetimes
Specifically, I noticed that my_rrule.dtstart has the representation
datetime.datetime(2017, 2, 8, 14, 0, tzinfo=tzutc())
whereas my_rrule2._dtstart is
datetime.datetime(2017, 2, 8, 14, 0)
Why is the timezone information lost? Is this not a deficiency in the __str__/rrulestr combination?

Django Auth user date_joined field datetime to string

When i am fetching the stored datetime value from auth user in django the value comes as below is there a way to convert this into normal date time format may be like "dd:mm:yyyy hh:mm:ss" or some string value that can be displayed in better(other) format
date_joined = request.user.date_joined
#date_joined value is
#datetime.datetime(2016, 9, 11, 16, 6, 22, 314637, tzinfo=<UTC>)
You can format a datetime object using its strftime() method, for example like this:
date_joined = request.user.date_joined
date_joined.strftime("%d:%m:%y %H:M:S")
If you want to display a datetime object in Django template, you can use the builtin date filter.
{{ date_joined|date:"d:m:Y H:i:s")

python compare datetimes with different timezones

I'm implementing feature with scheduled publishing of object.
User chooses the time to publish and i created a cron task to run every minute and check if it's the time to publish.
Users are from different timezones.
So i need to compare two datetimes:
>>user_chosen_time
datetime.datetime(2012, 12, 4, 14, 0, tzinfo=tzinfo(120))
>>curdate=datetime.datetime.now()
datetime.datetime(2012, 12, 4, 18, 4, 20, 17340)
>>user_chosen_time==curdate
*** TypeError: can't compare offset-naive and offset-aware datetimes
Sorry for rather stupid question but i need to discuss this. Thanks
As the error suggests you "can't compare offset-naive and offset-aware datetimes". It means that you should compare two datetimes that are both timezone-aware or both timezone-naive (not timezone-aware). In your codes, curdate has no timezone info and thus could not be compared with user_chosen_time which is timezone-aware.
First you should assign correct timezone to each datetime. And then you could directly compare two datetimes with different timezones.
Example (with pytz):
import pytz
import datetime as dt
# create timezone
nytz=pytz.timezone('America/New_York')
jptz=pytz.timezone('Asia/Tokyo')
# randomly initiate two timestamps
a=dt.datetime(2018,12,13,11,2)
b=dt.datetime(2018,12,13,22,45)
# assign timezone to timestamps
a=nytz.localize(a)
b=jptz.localize(b)
# a = datetime.datetime(2018, 12, 13, 11, 2, tzinfo=<DstTzInfo 'America/New_York' EST-1 day, 19:00:00 STD>)
# b = datetime.datetime(2018, 12, 13, 22, 45, tzinfo=<DstTzInfo 'Asia/Tokyo' JST+9:00:00 STD>)
a>b # True
b>a # False
For other methods you could refer to Convert a python UTC datetime to a local datetime using only python standard library?.
http://pytz.sourceforge.net/ is where you want to look when you want to eliminate the timezone differencies :)
edit: just found this post on SO that may give you a lot more informations on your problem

pytz: getting all timezones, where now is specific time

In DB I have table (User), which store timezone (as a string value, for ex.: "Europe/Oslo") for that user.
Now, I need to get all Users, where local time now is for ex.: 9AM.
Is there any good way of doing this, w/o making loop over all Users? If pytz is able to return list of timezones, where for now time is 9AM, I can use simple IN SQL statement.
import datetime
import pytz
now = datetime.now(pytz.utc)
# datetime.datetime(2012, 6, 8, 10, 31, 58, 493905, tzinfo=<UTC>)
[tz for tz in pytz.common_timezones_set if now.astimezone(pytz.timezone(tz)).hour == 9]
# ['Atlantic/Cape_Verde']
[tz for tz in pytz.common_timezones_set if now.astimezone(pytz.timezone(tz)).hour == 12]
# returns a list of 45 timezones, 'Europe/Oslo' included

Categories