From 1199780155f666b6806d563a29d093a251664009 Mon Sep 17 00:00:00 2001 From: Daniel Baumann Date: Sat, 30 Jan 2021 09:13:47 +0100 Subject: Adding upstream version 2.1.2. Signed-off-by: Daniel Baumann --- pendulum/formatting/difference_formatter.py | 153 ++++++++++++++++++++++++++++ 1 file changed, 153 insertions(+) create mode 100644 pendulum/formatting/difference_formatter.py (limited to 'pendulum/formatting/difference_formatter.py') diff --git a/pendulum/formatting/difference_formatter.py b/pendulum/formatting/difference_formatter.py new file mode 100644 index 0000000..3243089 --- /dev/null +++ b/pendulum/formatting/difference_formatter.py @@ -0,0 +1,153 @@ +import typing + +import pendulum + +from pendulum.utils._compat import decode + +from ..locales.locale import Locale + + +class DifferenceFormatter(object): + """ + Handles formatting differences in text. + """ + + def __init__(self, locale="en"): + self._locale = Locale.load(locale) + + def format( + self, diff, is_now=True, absolute=False, locale=None + ): # type: (pendulum.Period, bool, bool, typing.Optional[str]) -> str + """ + Formats a difference. + + :param diff: The difference to format + :type diff: pendulum.period.Period + + :param is_now: Whether the difference includes now + :type is_now: bool + + :param absolute: Whether it's an absolute difference or not + :type absolute: bool + + :param locale: The locale to use + :type locale: str or None + + :rtype: str + """ + if locale is None: + locale = self._locale + else: + locale = Locale.load(locale) + + count = diff.remaining_seconds + + if diff.years > 0: + unit = "year" + count = diff.years + + if diff.months > 6: + count += 1 + elif diff.months == 11 and (diff.weeks * 7 + diff.remaining_days) > 15: + unit = "year" + count = 1 + elif diff.months > 0: + unit = "month" + count = diff.months + + if (diff.weeks * 7 + diff.remaining_days) >= 27: + count += 1 + elif diff.weeks > 0: + unit = "week" + count = diff.weeks + + if diff.remaining_days > 3: + count += 1 + elif diff.remaining_days > 0: + unit = "day" + count = diff.remaining_days + + if diff.hours >= 22: + count += 1 + elif diff.hours > 0: + unit = "hour" + count = diff.hours + elif diff.minutes > 0: + unit = "minute" + count = diff.minutes + elif 10 < diff.remaining_seconds <= 59: + unit = "second" + count = diff.remaining_seconds + else: + # We check if the "a few seconds" unit exists + time = locale.get("custom.units.few_second") + if time is not None: + if absolute: + return time + + key = "custom" + is_future = diff.invert + if is_now: + if is_future: + key += ".from_now" + else: + key += ".ago" + else: + if is_future: + key += ".after" + else: + key += ".before" + + return locale.get(key).format(time) + else: + unit = "second" + count = diff.remaining_seconds + + if count == 0: + count = 1 + + if absolute: + key = "translations.units.{}".format(unit) + else: + is_future = diff.invert + + if is_now: + # Relative to now, so we can use + # the CLDR data + key = "translations.relative.{}".format(unit) + + if is_future: + key += ".future" + else: + key += ".past" + else: + # Absolute comparison + # So we have to use the custom locale data + + # Checking for special pluralization rules + key = "custom.units_relative" + if is_future: + key += ".{}.future".format(unit) + else: + key += ".{}.past".format(unit) + + trans = locale.get(key) + if not trans: + # No special rule + time = locale.get( + "translations.units.{}.{}".format(unit, locale.plural(count)) + ).format(count) + else: + time = trans[locale.plural(count)].format(count) + + key = "custom" + if is_future: + key += ".after" + else: + key += ".before" + + return locale.get(key).format(decode(time)) + + key += ".{}".format(locale.plural(count)) + + return decode(locale.get(key).format(count)) -- cgit v1.2.3