2023-01-05 10:14:00 +00:00
|
|
|
from datetime import datetime, timedelta
|
2023-01-04 18:19:49 +00:00
|
|
|
from django.conf import settings
|
|
|
|
from zoneinfo import ZoneInfo
|
2023-01-05 10:14:00 +00:00
|
|
|
import re
|
2023-01-04 18:19:49 +00:00
|
|
|
|
|
|
|
|
2023-01-05 10:24:31 +00:00
|
|
|
def now() -> datetime:
|
2023-01-04 18:19:49 +00:00
|
|
|
return datetime.now(ZoneInfo(settings.TIME_ZONE))
|
2023-01-05 10:14:00 +00:00
|
|
|
|
|
|
|
|
|
|
|
def format_duration(
|
|
|
|
duration: timedelta, format_string: str = "%H hours %m minutes"
|
|
|
|
) -> str:
|
|
|
|
"""
|
|
|
|
Format timedelta into the specified format_string.
|
|
|
|
Valid format variables:
|
|
|
|
- %H hours
|
|
|
|
- %m minutes
|
|
|
|
- %s seconds
|
2023-01-05 14:18:57 +00:00
|
|
|
- %r total seconds
|
2023-01-05 10:14:00 +00:00
|
|
|
"""
|
2023-01-05 14:18:57 +00:00
|
|
|
minute_seconds = 60
|
|
|
|
hour_seconds = 60 * minute_seconds
|
|
|
|
day_seconds = 24 * hour_seconds
|
2023-01-05 21:00:51 +00:00
|
|
|
if not isinstance(duration, timedelta):
|
|
|
|
duration = timedelta(seconds=duration)
|
2023-01-05 14:18:57 +00:00
|
|
|
seconds_total = int(duration.total_seconds())
|
2023-01-05 16:13:45 +00:00
|
|
|
# timestamps where end is before start
|
|
|
|
if seconds_total < 0:
|
|
|
|
seconds_total = 0
|
2023-01-05 14:18:57 +00:00
|
|
|
days, remainder = divmod(seconds_total, day_seconds)
|
|
|
|
hours, remainder = divmod(remainder, hour_seconds)
|
|
|
|
minutes, seconds = divmod(remainder, minute_seconds)
|
|
|
|
literals = {
|
|
|
|
"%d": str(days),
|
|
|
|
"%H": str(hours),
|
|
|
|
"%m": str(minutes),
|
|
|
|
"%s": str(seconds),
|
|
|
|
"%r": str(seconds_total),
|
|
|
|
}
|
|
|
|
formatted_string = format_string
|
|
|
|
for pattern, replacement in literals.items():
|
|
|
|
formatted_string = re.sub(pattern, replacement, formatted_string)
|
|
|
|
return formatted_string
|