datesformats.py 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143
  1. import math
  2. from datetime import datetime, timedelta
  3. from django.utils.dateformat import format, time_format
  4. from django.utils.formats import get_format
  5. from django.utils.timezone import is_aware, localtime, utc
  6. from django.utils.translation import pgettext, ungettext, ugettext as _
  7. from misago.utils.strings import slugify
  8. # Build date formats
  9. formats = {
  10. 'DATE_FORMAT': '',
  11. 'DATETIME_FORMAT': '',
  12. 'TIME_FORMAT': '',
  13. 'YEAR_MONTH_FORMAT': '',
  14. 'MONTH_DAY_FORMAT': '',
  15. 'SHORT_DATE_FORMAT': '',
  16. 'SHORT_DATETIME_FORMAT': '',
  17. }
  18. for key in formats:
  19. formats[key] = get_format(key).replace('P', 'g:i a')
  20. def date(val, arg=""):
  21. if not val:
  22. return _("Never")
  23. if not arg:
  24. arg = formats['DATE_FORMAT']
  25. elif arg in formats:
  26. arg = formats[arg]
  27. return format(localtime(val), arg)
  28. def reldate(val, arg=""):
  29. if not val:
  30. return _("Never")
  31. now = datetime.now(utc if is_aware(val) else None)
  32. local_now = localtime(now)
  33. diff = now - val
  34. local = localtime(val)
  35. # Today check
  36. if format(local, 'Y-z') == format(local_now, 'Y-z'):
  37. return _("Today, %(hour)s") % {'hour': time_format(local, formats['TIME_FORMAT'])}
  38. # Yesteday check
  39. yesterday = localtime(now - timedelta(days=1))
  40. if format(local, 'Y-z') == format(yesterday, 'Y-z'):
  41. return _("Yesterday, %(hour)s") % {'hour': time_format(local, formats['TIME_FORMAT'])}
  42. # Tomorrow Check
  43. tomorrow = localtime(now + timedelta(days=1))
  44. if format(local, 'Y-z') == format(tomorrow, 'Y-z'):
  45. return _("Tomorrow, %(hour)s") % {'hour': time_format(local, formats['TIME_FORMAT'])}
  46. # Day of Week check
  47. if format(local, 'D') != format(local_now, 'D') and diff.days > -7 and diff.days < 7:
  48. return _("%(day)s, %(hour)s") % {'day': format(local, 'l'), 'hour': time_format(local, formats['TIME_FORMAT'])}
  49. # Fallback to date
  50. return date(val, arg)
  51. def reltimesince(val, arg=""):
  52. if not val:
  53. return _("Never")
  54. now = datetime.now(utc if is_aware(val) else None)
  55. diff = now - val
  56. local = localtime(val)
  57. # Difference is greater than day for sure
  58. if diff.days != 0:
  59. return reldate(val, arg)
  60. # Display specific time
  61. if diff.seconds >= 0:
  62. if diff.seconds <= 5:
  63. return _("Just now")
  64. if diff.seconds < 3540:
  65. minutes = int(math.ceil(diff.seconds / 60.0))
  66. return ungettext(
  67. "Minute ago",
  68. "%(minutes)s minutes ago",
  69. minutes) % {'minutes': minutes}
  70. if diff.seconds < 3660:
  71. return _("Hour ago")
  72. if diff.seconds < 10800:
  73. hours = int(math.floor(diff.seconds / 3600.0))
  74. minutes = (diff.seconds - (hours * 3600)) / 60
  75. if minutes > 0:
  76. return ungettext(
  77. "Hour and %(minutes)s ago",
  78. "%(hours)s hours and %(minutes)s ago",
  79. hours) % {'hours': hours, 'minutes': ungettext(
  80. "%(minutes)s minute",
  81. "%(minutes)s minutes",
  82. minutes) % {'minutes': minutes}}
  83. return ungettext(
  84. "Hour ago",
  85. "%(hours)s hours ago",
  86. hours) % {'hours': hours}
  87. # Fallback to reldate
  88. return reldate(val, arg)
  89. def compact(val):
  90. if not val:
  91. return _("Never")
  92. now = datetime.now(utc if is_aware(val) else None)
  93. local = localtime(val)
  94. if now.year == local.year:
  95. return format(localtime(val), _('j M'))
  96. return format(localtime(val), _('j M y'))
  97. def relcompact(val):
  98. if not val:
  99. return _("Never")
  100. now = datetime.now(utc if is_aware(val) else None)
  101. diff = now - val
  102. local = localtime(val)
  103. # Difference is greater than day for sure
  104. if diff.days != 0:
  105. return compact(val)
  106. if diff.seconds >= 0:
  107. if diff.seconds <= 60:
  108. return _("Now")
  109. if diff.seconds < 3600:
  110. minutes = int(math.ceil(diff.seconds / 60.0))
  111. return pgettext("number of minutes", "%(minute)sm") % {'minute': minutes}
  112. if diff.seconds < 86400:
  113. hours = int(math.ceil(diff.seconds / 3600.0))
  114. return pgettext("number of hours", "%(hour)sh") % {'hour': hours}
  115. return compact(val)