Make format_duration more robust
continuous-integration/drone/push Build is passing
Details
continuous-integration/drone/push Build is passing
Details
This commit is contained in:
parent
49723831e9
commit
078f87687f
|
@ -1,6 +1,7 @@
|
|||
## Unreleased
|
||||
## 0.2.0 / 2023-01-09 22:42+01:00
|
||||
|
||||
* Show playtime total on session list (https://git.kucharczyk.xyz/lukas/timetracker/issues/6)
|
||||
* Make formatting durations more robust, change default duration display to "X hours" (https://git.kucharczyk.xyz/lukas/timetracker/issues/26)
|
||||
|
||||
## 0.1.4 / 2023-01-08 15:45+01:00
|
||||
|
||||
|
|
|
@ -6,7 +6,7 @@ RUN npm install && \
|
|||
|
||||
FROM python:3.10.9-alpine
|
||||
|
||||
ENV VERSION_NUMBER 0.1.2-11-g025ea0d
|
||||
ENV VERSION_NUMBER 0.2.0
|
||||
ENV PROD 1
|
||||
|
||||
RUN apk add \
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
[tool.poetry]
|
||||
name = "timetracker"
|
||||
version = "0.1.2"
|
||||
version = "0.2.0"
|
||||
description = "A simple time tracker."
|
||||
authors = ["Lukáš Kucharczyk <lukas@kucharczyk.xyz>"]
|
||||
license = "GPL"
|
||||
|
|
|
@ -18,7 +18,7 @@ def _safe_timedelta(duration: timedelta | int | None):
|
|||
|
||||
|
||||
def format_duration(
|
||||
duration: timedelta | int | None, format_string: str = "%H hours %m minutes"
|
||||
duration: timedelta | int | None, format_string: str = "%H hours"
|
||||
) -> str:
|
||||
"""
|
||||
Format timedelta into the specified format_string.
|
||||
|
@ -27,6 +27,10 @@ def format_duration(
|
|||
- %m minutes
|
||||
- %s seconds
|
||||
- %r total seconds
|
||||
Values don't change into higher units if those units are missing
|
||||
from the formatting string. For example:
|
||||
- 61 seconds as "%s" = 61 seconds
|
||||
- 61 seconds as "%m %s" = 1 minutes 1 seconds"
|
||||
"""
|
||||
minute_seconds = 60
|
||||
hour_seconds = 60 * minute_seconds
|
||||
|
@ -37,9 +41,14 @@ def format_duration(
|
|||
# timestamps where end is before start
|
||||
if seconds_total < 0:
|
||||
seconds_total = 0
|
||||
days, remainder = divmod(seconds_total, day_seconds)
|
||||
hours, remainder = divmod(remainder, hour_seconds)
|
||||
minutes, seconds = divmod(remainder, minute_seconds)
|
||||
days = hours = minutes = seconds = 0
|
||||
remainder = seconds = seconds_total
|
||||
if "%d" in format_string:
|
||||
days, remainder = divmod(seconds_total, day_seconds)
|
||||
if "%H" in format_string:
|
||||
hours, remainder = divmod(remainder, hour_seconds)
|
||||
if "%m" in format_string:
|
||||
minutes, seconds = divmod(remainder, minute_seconds)
|
||||
literals = {
|
||||
"%d": str(days),
|
||||
"%H": str(hours),
|
||||
|
|
|
@ -18,15 +18,40 @@ class FormatDurationTest(unittest.TestCase):
|
|||
result = format_duration(delta, "%H hours")
|
||||
self.assertEqual(result, "1 hours")
|
||||
|
||||
def test_overflow_hours(self):
|
||||
delta = timedelta(hours=25)
|
||||
result = format_duration(delta, "%H hours")
|
||||
self.assertEqual(result, "25 hours")
|
||||
|
||||
def test_overflow_hours_into_days(self):
|
||||
delta = timedelta(hours=25)
|
||||
result = format_duration(delta, "%d days, %H hours")
|
||||
self.assertEqual(result, "1 days, 1 hours")
|
||||
|
||||
def test_only_minutes(self):
|
||||
delta = timedelta(minutes=34)
|
||||
result = format_duration(delta, "%m minutes")
|
||||
self.assertEqual(result, "34 minutes")
|
||||
|
||||
def test_only_overflow_minutes(self):
|
||||
delta = timedelta(minutes=61)
|
||||
result = format_duration(delta, "%m minutes")
|
||||
self.assertEqual(result, "61 minutes")
|
||||
|
||||
def test_overflow_minutes_into_hours(self):
|
||||
delta = timedelta(minutes=61)
|
||||
result = format_duration(delta, "%H hours, %m minutes")
|
||||
self.assertEqual(result, "1 hours, 1 minutes")
|
||||
|
||||
def test_only_overflow_seconds(self):
|
||||
delta = timedelta(seconds=61)
|
||||
result = format_duration(delta, "%s seconds")
|
||||
self.assertEqual(result, "1 seconds")
|
||||
self.assertEqual(result, "61 seconds")
|
||||
|
||||
def test_overflow_seconds_into_minutes(self):
|
||||
delta = timedelta(seconds=61)
|
||||
result = format_duration(delta, "%m minutes, %s seconds")
|
||||
self.assertEqual(result, "1 minutes, 1 seconds")
|
||||
|
||||
def test_only_rawseconds(self):
|
||||
delta = timedelta(seconds=5690)
|
||||
|
@ -65,4 +90,3 @@ class FormatDurationTest(unittest.TestCase):
|
|||
|
||||
def test_number(self):
|
||||
self.assertEqual(format_duration(3600, "%H hour"), "1 hour")
|
||||
|
||||
|
|
Loading…
Reference in New Issue