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.

86 lines
1.9 KiB

  1. from datetime import datetime as dt
  2. from django.utils import timezone
  3. class Unit(object):
  4. def __init__(self, name, nsecs):
  5. self.name = name
  6. self.plural = name + "s"
  7. self.nsecs = nsecs
  8. SECOND = Unit("second", 1)
  9. MINUTE = Unit("minute", 60)
  10. HOUR = Unit("hour", MINUTE.nsecs * 60)
  11. DAY = Unit("day", HOUR.nsecs * 24)
  12. WEEK = Unit("week", DAY.nsecs * 7)
  13. def format_duration(td):
  14. remaining_seconds = int(td.total_seconds())
  15. result = []
  16. for unit in (WEEK, DAY, HOUR, MINUTE):
  17. if unit == WEEK and remaining_seconds % unit.nsecs != 0:
  18. # Say "8 days" instead of "1 week 1 day"
  19. continue
  20. v, remaining_seconds = divmod(remaining_seconds, unit.nsecs)
  21. if v == 1:
  22. result.append("1 %s" % unit.name)
  23. elif v > 1:
  24. result.append("%d %s" % (v, unit.plural))
  25. return " ".join(result)
  26. def format_hms(td):
  27. total_seconds = td.total_seconds()
  28. if 0.01 <= total_seconds < 1:
  29. return "%.2f sec" % total_seconds
  30. total_seconds = int(total_seconds)
  31. result = []
  32. mins, secs = divmod(total_seconds, 60)
  33. h, mins = divmod(mins, 60)
  34. if h:
  35. result.append("%d h" % h)
  36. if h or mins:
  37. result.append("%d min" % mins)
  38. result.append("%s sec" % secs)
  39. return " ".join(result)
  40. def format_approx_duration(td):
  41. v = td.total_seconds()
  42. for unit in (DAY, HOUR, MINUTE, SECOND):
  43. if v >= unit.nsecs:
  44. vv = v // unit.nsecs
  45. if vv == 1:
  46. return "1 %s" % unit.name
  47. else:
  48. return "%d %s" % (vv, unit.plural)
  49. return ""
  50. def month_boundaries(months):
  51. result = []
  52. now = timezone.now()
  53. y, m = now.year, now.month
  54. for x in range(0, months):
  55. result.insert(0, dt(y, m, 1, tzinfo=timezone.utc))
  56. m -= 1
  57. if m == 0:
  58. m = 12
  59. y = y - 1
  60. return result