Experimental Discord bot written in Python
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253
  1. import re
  2. from datetime import timedelta
  3. def parse_timedelta(s: str) -> timedelta:
  4. """
  5. Parses a timespan. Format examples:
  6. "30m"
  7. "10s"
  8. "90d"
  9. "1h30m"
  10. "73d18h22m52s"
  11. """
  12. p = re.compile('^(?:[0-9]+[dhms])+$')
  13. if p.match(s) is None:
  14. raise ValueError("Illegal timespan value '{s}'.")
  15. p = re.compile('([0-9]+)([dhms])')
  16. days = 0
  17. hours = 0
  18. minutes = 0
  19. seconds = 0
  20. for m in p.finditer(s):
  21. scalar = int(m.group(1))
  22. unit = m.group(2)
  23. if unit == 'd':
  24. days = scalar
  25. elif unit == 'h':
  26. hours = scalar
  27. elif unit == 'm':
  28. minutes = scalar
  29. elif unit == 's':
  30. seconds = scalar
  31. return timedelta(days=days, hours=hours, minutes=minutes, seconds=seconds)
  32. def describe_timedelta(td: timedelta, max_components: int = 2) -> str:
  33. """
  34. Formats a human-readable description of a time span. E.g. "3 days 2 hours".
  35. """
  36. d = td.days
  37. h = td.seconds // 3600
  38. m = (td.seconds // 60) % 60
  39. s = td.seconds % 60
  40. components = []
  41. if d != 0:
  42. components.append('1 day' if d == 1 else f'{d} days')
  43. if h != 0:
  44. components.append('1 hour' if h == 1 else f'{h} hours')
  45. if m != 0:
  46. components.append('1 minute' if m == 1 else f'{m} minutes')
  47. if s != 0 or len(components) == 0:
  48. components.append('1 second' if s == 1 else f'{s} seconds')
  49. if len(components) > max_components:
  50. components = components[0:max_components]
  51. return ' '.join(components)