From 9d0572ba925991d09d3ad5f3f83d145dc3f24622 Mon Sep 17 00:00:00 2001 From: Christopher Charbonneau Wells Date: Fri, 25 Aug 2017 16:33:14 -0400 Subject: [PATCH] Move duration methods in to utils for use elsewhere in the project. --- core/templatetags/duration.py | 64 ++++++++++++++++++----------------- core/utils.py | 28 +++++++++++++++ 2 files changed, 61 insertions(+), 31 deletions(-) diff --git a/core/templatetags/duration.py b/core/templatetags/duration.py index 1b1ad0de..02a17748 100644 --- a/core/templatetags/duration.py +++ b/core/templatetags/duration.py @@ -1,54 +1,56 @@ # -*- coding: utf-8 -*- from __future__ import unicode_literals -from datetime import timedelta - from django import template +from core.utils import duration_parts, duration_string as d_string + register = template.Library() @register.filter def duration_string(duration): - h, m, s = _get_hms(duration) - - duration = '' - if h > 0: - duration = '{} hour{}'.format(h, 's' if h > 1 else '') - if m > 0: - duration += '{}{} minute{}'.format( - '' if duration is '' else ', ', m, 's' if m > 1 else '') - if s > 0: - duration += '{}{} second{}'.format( - '' if duration is '' else ', ', s, 's' if s > 1 else '') - - return duration + """Format a duration (e.g. "2 hours, 3 minutes, 35 seconds").""" + if not duration: + return '' + try: + return d_string(duration) + except (ValueError, TypeError): + return '' @register.filter def hours(duration): - h, m, s = _get_hms(duration) - return h + """Return "hours" portion of a duration.""" + if not duration: + return 0 + try: + h, m, s = duration_parts(duration) + return h + except (ValueError, TypeError): + return 0 @register.filter def minutes(duration): - h, m, s = _get_hms(duration) - return m + """Return "minutes" portion of a duration.""" + if not duration: + return 0 + try: + h, m, s = duration_parts(duration) + return m + except (ValueError, TypeError): + return 0 @register.filter def seconds(duration): - h, m, s = _get_hms(duration) - return s - - -def _get_hms(duration): - """Get hours, minutes and seconds from a timedelta.""" - if not isinstance(duration, timedelta): - return 0, 0, 0 - h, remainder = divmod(duration.seconds, 3600) - h += duration.days * 24 - m, s = divmod(remainder, 60) - return h, m, s + """Return "seconds" portion of a duration.""" + if not duration: + return 0 + try: + h, m, s = duration_parts(duration) + return s + except (ValueError, TypeError): + return 0 diff --git a/core/utils.py b/core/utils.py index 4f3a75e2..1732fd7b 100644 --- a/core/utils.py +++ b/core/utils.py @@ -23,3 +23,31 @@ def timer_stop(timer_id, end=None): timer_instance = Timer.objects.get(id=timer_id) timer_instance.end = end timer_instance.save() + + +def duration_string(duration): + """Format hours, minutes and seconds in a human-friendly way (e.g. "2 + hours, 25 minutes, 31 seconds")""" + h, m, s = duration_parts(duration) + + duration = '' + if h > 0: + duration = '{} hour{}'.format(h, 's' if h > 1 else '') + if m > 0: + duration += '{}{} minute{}'.format( + '' if duration is '' else ', ', m, 's' if m > 1 else '') + if s > 0: + duration += '{}{} second{}'.format( + '' if duration is '' else ', ', s, 's' if s > 1 else '') + + return duration + + +def duration_parts(duration): + """Get hours, minutes and seconds from a timedelta.""" + if not isinstance(duration, timezone.timedelta): + raise TypeError('Duration provided must be a timedetla') + h, remainder = divmod(duration.seconds, 3600) + h += duration.days * 24 + m, s = divmod(remainder, 60) + return h, m, s \ No newline at end of file