Search code examples
pythondjangodjango-modelsdjango-querysetdjango-timezone

Filter objects with a datetime range (00:00 to 23:59:99) in Django


I used django model filter with date.

Origin data has time of Africa/Abidjan(UTC+00:00) and I save this data on my database.

I set timezone about Asia/Seoul(UTC+09:00)and it's save well in my database.

But I filter data with time_range=[2015-11-15, 2015-11-16], I got data about from 15 o'clock to 14 o'clock. I want to get data from 0 o'clock to 23 o'clock.

How can I get this? I do this url, but it doesn't work well.

class Post(models.Model):
    created_time = models.DateTimeField()

If I have a model like post, and I get date from user.

input_date = '2015-11-16' (from user)
from_date = datetime.strptime(input_date, '%Y-%m-%d').date()
to_date = from_date + datetime.timedelta(days=1)
posts = Post.objects.filter(created_time__range=[from_date, to_date])

I used upper code and got data from 2015-11-15 15:00:00 to 2015-11-16 14:00:00.

enter image description hereenter image description hereenter image description here


Solution

  • Here is what you can to to have a range datetime from 2015-11-16 00:00 to 2015-11-16 23:59:99

    from datetime import datetime as dt
    import datetime 
    
    input_date = '2015-11-16'
    # convert string to datetime
    from_date = dt.strptime(input_date, '%Y-%m-%d').date()
    # combine `from_date` with min time value (00:00)
    from_date = datetime.datetime.combine(from_date, datetime.time.min)
    # combine `from_date` with max time value (23:59:99) to have end date
    to_date = datetime.datetime.combine(from_date, datetime.time.max)
    posts = Post.objects.filter(created_time__range=(from_date, to_date))
    

    You can also use :

    from datetime import datetime
    
    input_date = '2015-11-16'
    # convert string to datetime
    from_date = datetime.strptime(input_date, '%Y-%m-%d').date()
    posts = Post.objects.filter(
        created_time__year=from_date.year, 
        created_time__month=from_date.month,
        created_time__day=from_date.day,
    )
    

    In your case, use :

    datetime.datetime.combine(from_date,datetime.time.max).replace(tzinfo=timezone.utc)