Coverage for /pythoncovmergedfiles/medio/medio/usr/local/lib/python3.8/site-packages/pendulum/formatting/difference_formatter.py: 9%
85 statements
« prev ^ index » next coverage.py v7.2.7, created at 2023-06-07 06:35 +0000
« prev ^ index » next coverage.py v7.2.7, created at 2023-06-07 06:35 +0000
1import typing
3import pendulum
5from pendulum.utils._compat import decode
7from ..locales.locale import Locale
10class DifferenceFormatter(object):
11 """
12 Handles formatting differences in text.
13 """
15 def __init__(self, locale="en"):
16 self._locale = Locale.load(locale)
18 def format(
19 self, diff, is_now=True, absolute=False, locale=None
20 ): # type: (pendulum.Period, bool, bool, typing.Optional[str]) -> str
21 """
22 Formats a difference.
24 :param diff: The difference to format
25 :type diff: pendulum.period.Period
27 :param is_now: Whether the difference includes now
28 :type is_now: bool
30 :param absolute: Whether it's an absolute difference or not
31 :type absolute: bool
33 :param locale: The locale to use
34 :type locale: str or None
36 :rtype: str
37 """
38 if locale is None:
39 locale = self._locale
40 else:
41 locale = Locale.load(locale)
43 count = diff.remaining_seconds
45 if diff.years > 0:
46 unit = "year"
47 count = diff.years
49 if diff.months > 6:
50 count += 1
51 elif diff.months == 11 and (diff.weeks * 7 + diff.remaining_days) > 15:
52 unit = "year"
53 count = 1
54 elif diff.months > 0:
55 unit = "month"
56 count = diff.months
58 if (diff.weeks * 7 + diff.remaining_days) >= 27:
59 count += 1
60 elif diff.weeks > 0:
61 unit = "week"
62 count = diff.weeks
64 if diff.remaining_days > 3:
65 count += 1
66 elif diff.remaining_days > 0:
67 unit = "day"
68 count = diff.remaining_days
70 if diff.hours >= 22:
71 count += 1
72 elif diff.hours > 0:
73 unit = "hour"
74 count = diff.hours
75 elif diff.minutes > 0:
76 unit = "minute"
77 count = diff.minutes
78 elif 10 < diff.remaining_seconds <= 59:
79 unit = "second"
80 count = diff.remaining_seconds
81 else:
82 # We check if the "a few seconds" unit exists
83 time = locale.get("custom.units.few_second")
84 if time is not None:
85 if absolute:
86 return time
88 key = "custom"
89 is_future = diff.invert
90 if is_now:
91 if is_future:
92 key += ".from_now"
93 else:
94 key += ".ago"
95 else:
96 if is_future:
97 key += ".after"
98 else:
99 key += ".before"
101 return locale.get(key).format(time)
102 else:
103 unit = "second"
104 count = diff.remaining_seconds
106 if count == 0:
107 count = 1
109 if absolute:
110 key = "translations.units.{}".format(unit)
111 else:
112 is_future = diff.invert
114 if is_now:
115 # Relative to now, so we can use
116 # the CLDR data
117 key = "translations.relative.{}".format(unit)
119 if is_future:
120 key += ".future"
121 else:
122 key += ".past"
123 else:
124 # Absolute comparison
125 # So we have to use the custom locale data
127 # Checking for special pluralization rules
128 key = "custom.units_relative"
129 if is_future:
130 key += ".{}.future".format(unit)
131 else:
132 key += ".{}.past".format(unit)
134 trans = locale.get(key)
135 if not trans:
136 # No special rule
137 time = locale.get(
138 "translations.units.{}.{}".format(unit, locale.plural(count))
139 ).format(count)
140 else:
141 time = trans[locale.plural(count)].format(count)
143 key = "custom"
144 if is_future:
145 key += ".after"
146 else:
147 key += ".before"
149 return locale.get(key).format(decode(time))
151 key += ".{}".format(locale.plural(count))
153 return decode(locale.get(key).format(count))