> I want to compare dates in my db while ignoring the year field. Lets
> say I have a birthday field and want to find upcoming birthdays in the
> next one week. How can I achieve this? If I try-
>
> last_date = datetime.now().date() + timedelta(days=7)
> users = User.objects.filter(birthday__day__lte = last_date.day)
This is a bit tricky, especially because of boundary conditions
like ends-of-months and end-of-years. Note that if it's
currently December 28th, last_date.day isn't quite what you want
to be comparing to.
This can be done on the DB-server-side if you do server-specific
code; it can be done on the Django side in homogenous Python code
if you're willing to slurp over all your germane birthdays and
filter them locally; or, with such a small range of days (fixed
at 7), you could do something hackish like:
now = datetime.now().date()
dates = [now + timedelta(days=x) for x in xrange(8)]
from operator import or_
params = reduce(or_, [
Q(birthday__day=date.day, birthday__month=date.month)
for date in dates
])
users = User.objects.filter(*params)
This gets a little unweildy if you have more than a couple days
to consider (I don't think I'd do this for more than about 10
days). It basically builds something of the form
...filter(Q(birthday__day=now.day, birthday__month=now.month) |
Q(birthday__day=now.day + timedelta(days=1),
birthday__month=now.month + timedelta(days=1)) |
Q(birthday__day=now.day + timedelta(days=2),
birthday__month=now.month + timedelta(days=2)) |
Q(birthday__day=now.day + timedelta(days=3),
birthday__month=now.month + timedelta(days=3)) |
...
for each of your days. (thus a cap on 7 days is good...smaller
is better)
However, the alternative on the server side would be to write
DB-specific code doing some crazy date math using functions like
MySQL's DateAdd function. The high-level picture would involve
normalizing the field's date to the year that falls within the
given range and then comparing it with BETWEEN to ensure it falls
between the two calculated dates. Something like this 100%
untested code:
now = datetime.now().date()
end = now + timedelta(days=7)
users = User.objects.extra(where="""
adddate(birthday, interval
(Extract(year from %s) - Extract(year from birthday))
years)
BETWEEN %s AND %s
""",
params = [now, now, end])
You might have to tweak it to add 1 to the year if there's some
odd boundary straddling.
-tim
--~--~---------~--~----~------------~-------~--~----~
You received this message because you are subscribed to the Google Groups
"Django users" group.
To post to this group, send email to [email protected]
To unsubscribe from this group, send email to [EMAIL PROTECTED]
For more options, visit this group at
http://groups.google.com/group/django-users?hl=en
-~----------~----~----~----~------~----~------~--~---