Exemplo n.º 1
0
    def ordinalize(self, number):
        ordinal = self.get("custom.ordinal.{}".format(self.ordinal(number)))

        if not ordinal:
            return decode("{}".format(number))

        return decode("{}{}".format(number, ordinal))
Exemplo n.º 2
0
    def format(self, dt, fmt, locale=None):
        """
        Formats a DateTime instance with a given format and locale.

        :param dt: The instance to format
        :type dt: pendulum.DateTime

        :param fmt: The format to use
        :type fmt: str

        :param locale: The locale to use
        :type locale: str or Locale or None

        :rtype: str
        """
        if not locale:
            locale = pendulum.get_locale()

        locale = Locale.load(locale)

        result = self._FORMAT_RE.sub(
            lambda m: m.group(1) if m.group(1) else m.group(2)
            if m.group(2) else self._format_token(dt, m.group(3), locale),
            fmt,
        )

        return decode(result)
Exemplo n.º 3
0
    def format(self, dt, fmt, locale=None):
        """
        Formats a DateTime instance with a given format and locale.

        :param dt: The instance to format
        :type dt: pendulum.DateTime

        :param fmt: The format to use
        :type fmt: str

        :param locale: The locale to use
        :type locale: str or Locale or None

        :rtype: str
        """
        if not locale:
            locale = pendulum.get_locale()

        locale = Locale.load(locale)

        result = self._FORMAT_RE.sub(
            lambda m: m.group(1)
            if m.group(1)
            else m.group(2)
            if m.group(2)
            else self._format_token(dt, m.group(3), locale),
            fmt,
        )

        return decode(result)
Exemplo n.º 4
0
    def _replace_tokens(self, token, locale):  # type: (str, Locale) -> str
        if token.startswith('[') and token.endswith(']'):
            return token[1:-1]
        elif token.startswith('\\'):
            return token
        elif (token not in self._REGEX_TOKENS
              and token not in self._LOCALIZABLE_TOKENS):
            raise ValueError('Unsupported token: {}'.format(token))

        if token in self._LOCALIZABLE_TOKENS:
            values = self._LOCALIZABLE_TOKENS[token]
            if callable(values):
                candidates = values(locale)
            else:
                candidates = tuple(
                    locale.translation(
                        self._LOCALIZABLE_TOKENS[token]).values())
        else:
            candidates = self._REGEX_TOKENS[token]

        if not candidates:
            raise ValueError('Unsupported token: {}'.format(token))

        if not isinstance(candidates, tuple):
            candidates = (candidates, )

        pattern = '(?P<{}>{})'.format(
            token, '|'.join([decode(p) for p in candidates]))

        return pattern
Exemplo n.º 5
0
    def _replace_tokens(self, token, locale):  # type: (str, Locale) -> str
        if token.startswith("[") and token.endswith("]"):
            return token[1:-1]
        elif token.startswith("\\"):
            if len(token) == 2 and token[1] in {"[", "]"}:
                return ""

            return token
        elif token not in self._REGEX_TOKENS and token not in self._LOCALIZABLE_TOKENS:
            raise ValueError("Unsupported token: {}".format(token))

        if token in self._LOCALIZABLE_TOKENS:
            values = self._LOCALIZABLE_TOKENS[token]
            if callable(values):
                candidates = values(locale)
            else:
                candidates = tuple(
                    locale.translation(self._LOCALIZABLE_TOKENS[token]).values()
                )
        else:
            candidates = self._REGEX_TOKENS[token]

        if not candidates:
            raise ValueError("Unsupported token: {}".format(token))

        if not isinstance(candidates, tuple):
            candidates = (candidates,)

        pattern = "(?P<{}>{})".format(token, "|".join([decode(p) for p in candidates]))

        return pattern
Exemplo n.º 6
0
    def _replace_tokens(self, token, locale):  # type: (str, Locale) -> str
        if token.startswith("[") and token.endswith("]"):
            return token[1:-1]
        elif token.startswith("\\"):
            if len(token) == 2 and token[1] in {"[", "]"}:
                return ""

            return token
        elif token not in self._REGEX_TOKENS and token not in self._LOCALIZABLE_TOKENS:
            raise ValueError("Unsupported token: {}".format(token))

        if token in self._LOCALIZABLE_TOKENS:
            values = self._LOCALIZABLE_TOKENS[token]
            if callable(values):
                candidates = values(locale)
            else:
                candidates = tuple(
                    locale.translation(
                        self._LOCALIZABLE_TOKENS[token]).values())
        else:
            candidates = self._REGEX_TOKENS[token]

        if not candidates:
            raise ValueError("Unsupported token: {}".format(token))

        if not isinstance(candidates, tuple):
            candidates = (candidates, )

        pattern = "(?P<{}>{})".format(
            token, "|".join([decode(p) for p in candidates]))

        return pattern
Exemplo n.º 7
0
    def in_words(self, locale=None, separator=' '):
        """
        Get the current interval in words in the current locale.

        Ex: 6 jours 23 heures 58 minutes

        :param locale: The locale to use. Defaults to current locale.
        :type locale: str

        :param separator: The separator to use between each unit
        :type separator: str

        :rtype: str
        """
        periods = [
            ('year', self.years),
            ('month', self.months),
            ('week', self.weeks),
            ('day', self.remaining_days),
            ('hour', self.hours),
            ('minute', self.minutes),
            ('second', self.remaining_seconds)
        ]

        if locale is None:
            locale = pendulum.get_locale()

        locale = pendulum.locale(locale)
        parts = []
        for period in periods:
            unit, count = period
            if abs(count) > 0:
                translation = locale.translation(
                    'units.{}.{}'.format(
                        unit, locale.plural(abs(count))
                    )
                )
                parts.append(translation.format(count))

        if not parts and abs(self.microseconds) > 0:
            translation = locale.translation(
                'units.second.{}'.format(locale.plural(1))
            )
            us = abs(self.microseconds) / 1e6
            parts.append(
                translation.format('{:.2f}'.format(us))
            )

        return decode(separator.join(parts))
Exemplo n.º 8
0
    def in_words(self, locale=None, separator=" "):
        """
        Get the current interval in words in the current locale.

        Ex: 6 jours 23 heures 58 minutes

        :param locale: The locale to use. Defaults to current locale.
        :type locale: str

        :param separator: The separator to use between each unit
        :type separator: str

        :rtype: str
        """
        periods = [
            ("year", self.years),
            ("month", self.months),
            ("week", self.weeks),
            ("day", self.remaining_days),
            ("hour", self.hours),
            ("minute", self.minutes),
            ("second", self.remaining_seconds),
        ]

        if locale is None:
            locale = pendulum.get_locale()

        locale = pendulum.locale(locale)
        parts = []
        for period in periods:
            unit, count = period
            if abs(count) > 0:
                translation = locale.translation(
                    "units.{}.{}".format(unit, locale.plural(abs(count)))
                )
                parts.append(translation.format(count))

        if not parts:
            if abs(self.microseconds) > 0:
                unit = "units.second.{}".format(locale.plural(1))
                count = "{:.2f}".format(abs(self.microseconds) / 1e6)
            else:
                unit = "units.microsecond.{}".format(locale.plural(0))
                count = 0
            translation = locale.translation(unit)
            parts.append(translation.format(count))

        return decode(separator.join(parts))
Exemplo n.º 9
0
    def get(self, key, default=None):
        if key in self._key_cache:
            return self._key_cache[key]

        parts = key.split(".")
        try:
            result = self._data[parts[0]]
            for part in parts[1:]:
                result = result[part]
        except KeyError:
            result = default

        if isinstance(result, basestring):
            result = decode(result)

        self._key_cache[key] = result

        return self._key_cache[key]
Exemplo n.º 10
0
    def in_words(self, locale=None, separator=" "):
        """
        Get the current interval in words in the current locale.

        Ex: 6 jours 23 heures 58 minutes

        :param locale: The locale to use. Defaults to current locale.
        :type locale: str

        :param separator: The separator to use between each unit
        :type separator: str

        :rtype: str
        """
        periods = [
            ("year", self.years),
            ("month", self.months),
            ("week", self.weeks),
            ("day", self.remaining_days),
            ("hour", self.hours),
            ("minute", self.minutes),
            ("second", self.remaining_seconds),
        ]

        if locale is None:
            locale = pendulum.get_locale()

        locale = pendulum.locale(locale)
        parts = []
        for period in periods:
            unit, count = period
            if abs(count) > 0:
                translation = locale.translation(
                    "units.{}.{}".format(unit, locale.plural(abs(count)))
                )
                parts.append(translation.format(count))

        if not parts and abs(self.microseconds) > 0:
            translation = locale.translation("units.second.{}".format(locale.plural(1)))
            us = abs(self.microseconds) / 1e6
            parts.append(translation.format("{:.2f}").format(us))

        return decode(separator.join(parts))
Exemplo n.º 11
0
 def ordinal(self, number):
     return decode(self._data["ordinal"](number))
Exemplo n.º 12
0
 def plural(self, number):
     return decode(self._data["plural"](number))
Exemplo n.º 13
0
 def plural(self, number):  # type: (int) -> str
     return decode(self._data["plural"](number))
Exemplo n.º 14
0
    def format(self,
               diff,
               is_now=True,
               absolute=False,
               locale=None
               ):  # type: (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))
Exemplo n.º 15
0
 def ordinal(self, number):
     return decode(self._data['ordinal'](number))
Exemplo n.º 16
0
 def plural(self, number):
     return decode(self._data['plural'](number))
Exemplo n.º 17
0
 def ordinal(self, number):  # type: (int) -> str
     return decode(self._data["ordinal"](number))
Exemplo n.º 18
0
    def format(self, diff, is_now=True, absolute=False, locale=None):
        """
        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))