Home > Net >  Have only hours and minutes in durationfield Django
Have only hours and minutes in durationfield Django

Time:02-10

I would like to have a duration field expressed just as hours and minutes. I post you my code: views.py

    log_entry = LogEntry.objects.filter(Q(date__range=[start_date, end_date]) & Q(
        student_id__id__icontains=student) & Q(instructor_id__id__icontains=instructor) & Q(aircraft_id__id__icontains=aircraft))

    total_flight_hours = log_entry_dual.aggregate(eet=Sum(ExpressionWrapper(
        F('ata') - F('etd'), output_field=IntegerField()), output_field=DurationField()))['eet']

Now, total_flight_hours is printed in my template as (for example) 03:00:00 which states for 3 hours. Since I just need hours and minutes and I don't care about seconds, is there a way to get rid of the seconds? Thank you very much in advance

CodePudding user response:

I'm not sure how your template is structured and where the hours and minutes are used. If a string would be accepted in your template that django passes to I think this would work:

from datetime import timedelta


def timedelta_to_hm(td: timedelta) -> str:
    if td.seconds % 60 > 29:
        td  = timedelta(seconds=30)
    a = str(td)
    b = a[-8:].lstrip(' ')
    return b[:-3]


timedelta_to_hm(timedelta(days=1, hours=2,minutes=20, seconds=0)) #  '2:20'
timedelta_to_hm(timedelta(hours=26,minutes=20, seconds=0)) #  '2:20'
timedelta_to_hm(timedelta(hours=21,minutes=20, seconds=31)) #  '21:21'
timedelta_to_hm(timedelta(hours=1,minutes=20, seconds=29)) #  '1:20'
timedelta_to_hm(timedelta(hours=1,minutes=20, seconds=31)) #  '1:21'
timedelta_to_hm(timedelta(hours=1,minutes=20, seconds=39)) #  '1:21'
timedelta_to_hm(timedelta(minutes=0, seconds=39)) #  '0:01'

Here I'm thinking something like this in your html template, where ctxt is the context with parametrized template data.

<p>We start at
   <time datetime={{ctxt.hours_minutes}}>{{ctxt.hours_minutes}}</time> 
   sharp. 
</p>

Note this drops leading 0s in the hours. If you want a leading 0 you can add one in cases where needed in the function. Also, I'm rounding up at 30 seconds. The default behavior without the round would be to always round down (analogous to integer division). This also assumes the hours and minutes are going into your template and you're not doing any other calculation on the hours and minutes.

If you want to do other calculations then it's best not to convert to a string and to proceed with calculations to extract the hours and minutes directly. Perhaps using one of the approaches described in another question here.

  • Related