mirror of
https://github.com/Second-Hand-Friends/kleinanzeigen-bot.git
synced 2026-03-12 10:31:50 +01:00
feat: add misc.format_timedelta/parse_duration
This commit is contained in:
@@ -5,10 +5,12 @@ SPDX-ArtifactOfProjectHomePage: https://github.com/Second-Hand-Friends/kleinanze
|
||||
"""
|
||||
import asyncio, decimal, re, sys, time
|
||||
from collections.abc import Callable
|
||||
from datetime import datetime
|
||||
from datetime import datetime, timedelta
|
||||
from gettext import gettext as _
|
||||
from typing import Any, TypeVar
|
||||
|
||||
from . import i18n
|
||||
|
||||
# https://mypy.readthedocs.io/en/stable/generics.html#generic-functions
|
||||
T = TypeVar('T')
|
||||
|
||||
@@ -53,14 +55,19 @@ def parse_decimal(number:float | int | str) -> decimal.Decimal:
|
||||
"""
|
||||
>>> parse_decimal(5)
|
||||
Decimal('5')
|
||||
|
||||
>>> parse_decimal(5.5)
|
||||
Decimal('5.5')
|
||||
|
||||
>>> parse_decimal("5.5")
|
||||
Decimal('5.5')
|
||||
|
||||
>>> parse_decimal("5,5")
|
||||
Decimal('5.5')
|
||||
|
||||
>>> parse_decimal("1.005,5")
|
||||
Decimal('1005.5')
|
||||
|
||||
>>> parse_decimal("1,005.5")
|
||||
Decimal('1005.5')
|
||||
"""
|
||||
@@ -78,8 +85,10 @@ def parse_datetime(date:datetime | str | None) -> datetime | None:
|
||||
"""
|
||||
>>> parse_datetime(datetime(2020, 1, 1, 0, 0))
|
||||
datetime.datetime(2020, 1, 1, 0, 0)
|
||||
|
||||
>>> parse_datetime("2020-01-01T00:00:00")
|
||||
datetime.datetime(2020, 1, 1, 0, 0)
|
||||
|
||||
>>> parse_datetime(None)
|
||||
|
||||
"""
|
||||
@@ -88,3 +97,79 @@ def parse_datetime(date:datetime | str | None) -> datetime | None:
|
||||
if isinstance(date, datetime):
|
||||
return date
|
||||
return datetime.fromisoformat(date)
|
||||
|
||||
|
||||
def parse_duration(text:str) -> timedelta:
|
||||
"""
|
||||
Parses a human-readable duration string into a datetime.timedelta.
|
||||
|
||||
Supported units:
|
||||
- d: days
|
||||
- h: hours
|
||||
- m: minutes
|
||||
- s: seconds
|
||||
|
||||
Examples:
|
||||
>>> parse_duration("1h 30m")
|
||||
datetime.timedelta(seconds=5400)
|
||||
|
||||
>>> parse_duration("2d 4h 15m 10s")
|
||||
datetime.timedelta(days=2, seconds=15310)
|
||||
|
||||
>>> parse_duration("45m")
|
||||
datetime.timedelta(seconds=2700)
|
||||
|
||||
>>> parse_duration("3d")
|
||||
datetime.timedelta(days=3)
|
||||
|
||||
>>> parse_duration("5h 5h")
|
||||
datetime.timedelta(seconds=36000)
|
||||
|
||||
>>> parse_duration("invalid input")
|
||||
datetime.timedelta(0)
|
||||
"""
|
||||
pattern = re.compile(r'(\d+)\s*([dhms])')
|
||||
parts = pattern.findall(text.lower())
|
||||
kwargs: dict[str, int] = {}
|
||||
for value, unit in parts:
|
||||
if unit == 'd':
|
||||
kwargs['days'] = kwargs.get('days', 0) + int(value)
|
||||
elif unit == 'h':
|
||||
kwargs['hours'] = kwargs.get('hours', 0) + int(value)
|
||||
elif unit == 'm':
|
||||
kwargs['minutes'] = kwargs.get('minutes', 0) + int(value)
|
||||
elif unit == 's':
|
||||
kwargs['seconds'] = kwargs.get('seconds', 0) + int(value)
|
||||
return timedelta(**kwargs)
|
||||
|
||||
|
||||
def format_timedelta(td: timedelta) -> str:
|
||||
"""
|
||||
Formats a timedelta into a human-readable string using the pluralize utility.
|
||||
|
||||
>>> format_timedelta(timedelta(seconds=90))
|
||||
'1 minute, 30 seconds'
|
||||
>>> format_timedelta(timedelta(hours=1))
|
||||
'1 hour'
|
||||
>>> format_timedelta(timedelta(days=2, hours=5))
|
||||
'2 days, 5 hours'
|
||||
>>> format_timedelta(timedelta(0))
|
||||
'0 seconds'
|
||||
"""
|
||||
days = td.days
|
||||
seconds = td.seconds
|
||||
hours, remainder = divmod(seconds, 3600)
|
||||
minutes, seconds = divmod(remainder, 60)
|
||||
|
||||
parts = []
|
||||
|
||||
if days:
|
||||
parts.append(i18n.pluralize("day", days))
|
||||
if hours:
|
||||
parts.append(i18n.pluralize("hour", hours))
|
||||
if minutes:
|
||||
parts.append(i18n.pluralize("minute", minutes))
|
||||
if seconds:
|
||||
parts.append(i18n.pluralize("second", seconds))
|
||||
|
||||
return ", ".join(parts) if parts else i18n.pluralize("second", 0)
|
||||
|
||||
Reference in New Issue
Block a user