I could be a bit more pythonic: >>> from django.db.models.query import QOr >>> ql = [Q(birthdate__day=(startdate + timedelta(days=x)).day) & >>> Q(birthdate__month=(startdate + timedelta(days=x)).month) for x in range(7)] >>> Person.objects.filter(QOr(*ql))
-rob On Jun 19, 2:51 pm, Tim Chase <[EMAIL PROTECTED]> wrote: > > 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 django-users@googlegroups.com 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 -~----------~----~----~----~------~----~------~--~---