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))
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)
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
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
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
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))
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))
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]
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))
def ordinal(self, number): return decode(self._data["ordinal"](number))
def plural(self, number): return decode(self._data["plural"](number))
def plural(self, number): # type: (int) -> str return decode(self._data["plural"](number))
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))
def ordinal(self, number): return decode(self._data['ordinal'](number))
def plural(self, number): return decode(self._data['plural'](number))
def ordinal(self, number): # type: (int) -> str return decode(self._data["ordinal"](number))
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))