def __init__(self, locale='en_us'): self.locale = locales.get_locale(locale) self._input_re_map = self._BASE_INPUT_RE_MAP.copy() self._input_re_map.update({ 'MMMM': self._choice_re(self.locale.month_names[1:], re.IGNORECASE), 'MMM': self._choice_re(self.locale.month_abbreviations[1:], re.IGNORECASE), 'Do': re.compile(self.locale.ordinal_day_re), 'dddd': self._choice_re(self.locale.day_names[1:], re.IGNORECASE), 'ddd': self._choice_re(self.locale.day_abbreviations[1:], re.IGNORECASE), 'd': re.compile("[1-7]"), 'a': self._choice_re( (self.locale.meridians['am'], self.locale.meridians['pm'])), # note: 'A' token accepts both 'am/pm' and 'AM/PM' formats to # ensure backwards compatibility of this token 'A': self._choice_re(self.locale.meridians.values()) })
def __init__(self, locale='en_us', cache_size=0): self.locale = locales.get_locale(locale) self._input_re_map = self._BASE_INPUT_RE_MAP.copy() self._input_re_map.update({ 'MMMM': self._choice_re(self.locale.month_names[1:], re.IGNORECASE), 'MMM': self._choice_re(self.locale.month_abbreviations[1:], re.IGNORECASE), 'Do': re.compile(self.locale.ordinal_day_re), 'dddd': self._choice_re(self.locale.day_names[1:], re.IGNORECASE), 'ddd': self._choice_re(self.locale.day_abbreviations[1:], re.IGNORECASE), 'd': re.compile(r"[1-7]"), 'a': self._choice_re( (self.locale.meridians['am'], self.locale.meridians['pm']) ), # note: 'A' token accepts both 'am/pm' and 'AM/PM' formats to # ensure backwards compatibility of this token 'A': self._choice_re(self.locale.meridians.values()) }) if cache_size > 0: self._generate_pattern_re =\ cast(Callable, lru_cache(maxsize=cache_size)(self.__generate_pattern_re)) else: self._generate_pattern_re = self.__generate_pattern_re
def __init__(self, locale="en_us", cache_size=0): self.locale = locales.get_locale(locale) self._input_re_map = self._BASE_INPUT_RE_MAP.copy() self._input_re_map.update( { "MMMM": self._generate_choice_re( self.locale.month_names[1:], re.IGNORECASE ), "MMM": self._generate_choice_re( self.locale.month_abbreviations[1:], re.IGNORECASE ), "Do": re.compile(self.locale.ordinal_day_re), "dddd": self._generate_choice_re( self.locale.day_names[1:], re.IGNORECASE ), "ddd": self._generate_choice_re( self.locale.day_abbreviations[1:], re.IGNORECASE ), "d": re.compile(r"[1-7]"), "a": self._generate_choice_re( (self.locale.meridians["am"], self.locale.meridians["pm"]) ), # note: 'A' token accepts both 'am/pm' and 'AM/PM' formats to # ensure backwards compatibility of this token "A": self._generate_choice_re(self.locale.meridians.values()), } ) if cache_size > 0: self._generate_pattern_re = lru_cache(maxsize=cache_size)( self._generate_pattern_re )
def __init__(self, locale='en_us'): self.locale = locales.get_locale(locale) self._input_re_map = self._BASE_INPUT_RE_MAP.copy() self._input_re_map.update({ 'MMMM': self._choice_re(self.locale.month_names[1:], re.IGNORECASE), 'MMM': self._choice_re(self.locale.month_abbreviations[1:], re.IGNORECASE) })
def __init__(self, locale='en_us'): self.locale = locales.get_locale(locale) self._input_re_map = self._BASE_INPUT_RE_MAP.copy() self._input_re_map.update({ 'MMMM': self._choice_re(self.locale.month_names[1:], re.IGNORECASE), 'MMM': self._choice_re(self.locale.month_abbreviations[1:], re.IGNORECASE), 'Do': re.compile(self.locale.ordinal_day_re) })
def test_get_locale(self): mock_locales = mock(locales, '_locales') mock_locale_cls = mock() mock_locale = mock() expect(mock_locales.get).args('name').returns(mock_locale_cls) expect(mock_locale_cls).returns(mock_locale) result = locales.get_locale('name') assertEqual(result, mock_locale)
def test_get_locale(self): mock_locales = self.mock(locales, "_locales") mock_locale_cls = self.mock() mock_locale = self.mock() self.expect(mock_locales.get).args("name").returns(mock_locale_cls) self.expect(mock_locale_cls).returns(mock_locale) result = locales.get_locale("name") self.assertEqual(result, mock_locale)
def test_get_locale(self): mock_locales = mock(locales, "_locales") mock_locale_cls = mock() mock_locale = mock() expect(mock_locales.get).args("name").returns(mock_locale_cls) expect(mock_locale_cls).returns(mock_locale) result = locales.get_locale("name") assertEqual(result, mock_locale)
def get_locale_aware_dt_str(reminder_dt, language=LANGUAGE_DEFAULT): locale = get_locale(language) str_format = 'dddd ' if len(locale.month_abbreviations) == 0: str_format += 'MMMM ' else: str_format += 'MMM ' str_format += 'D, ' if u'' in locale.meridians.values(): # Use a 24 hour clock str_format += 'H:mm' else: # Use 12 hour clock with meridian str_format += 'h:mm a' return arrow.get(reminder_dt).format(str_format, locale=language).replace(' ', ' ')
def __init__(self, locale='en_us'): self.locale = locales.get_locale(locale) self._input_re_map = self._BASE_INPUT_RE_MAP.copy() self._input_re_map.update({ 'MMMM': self._choice_re(self.locale.month_names[1:], re.IGNORECASE), 'MMM': self._choice_re(self.locale.month_abbreviations[1:], re.IGNORECASE), 'Do': re.compile(self.locale.ordinal_day_re), 'a': self._choice_re( (self.locale.meridians['am'], self.locale.meridians['pm']) ), # note: 'A' token accepts both 'am/pm' and 'AM/PM' formats to # ensure backwards compatibility of this token 'A': self._choice_re(self.locale.meridians.values()) })
def __init__(self, locale='en_us', cache_size=0): self.locale = locales.get_locale(locale) self._input_re_map = self._BASE_INPUT_RE_MAP.copy() self._input_re_map.update({ 'MMMM': self._choice_re(self.locale.month_names[1:], re.IGNORECASE), 'MMM': self._choice_re(self.locale.month_abbreviations[1:], re.IGNORECASE), 'Do': re.compile(self.locale.ordinal_day_re), 'dddd': self._choice_re(self.locale.day_names[1:], re.IGNORECASE), 'ddd': self._choice_re(self.locale.day_abbreviations[1:], re.IGNORECASE), 'd': re.compile(r"[1-7]"), 'a': self._choice_re( (self.locale.meridians['am'], self.locale.meridians['pm']) ), # note: 'A' token accepts both 'am/pm' and 'AM/PM' formats to # ensure backwards compatibility of this token 'A': self._choice_re(self.locale.meridians.values()) }) if cache_size > 0: self._generate_pattern_re =\ lru_cache(maxsize=cache_size)(self._generate_pattern_re)
def __init__(self, locale='en_us'): self.locale = locales.get_locale(locale)
def humanize(self, other=None, locale='en_us', only_distance=False): ''' Returns a localized, humanized representation of a relative difference in time. :param other: (optional) an :class:`Arrow <arrow.arrow.Arrow>` or ``datetime`` object. Defaults to now in the current :class:`Arrow <arrow.arrow.Arrow>` object's timezone. :param locale: (optional) a ``str`` specifying a locale. Defaults to 'en_us'. :param only_distance: (optional) returns only time difference eg: "11 seconds" without "in" or "ago" part. Usage:: >>> earlier = arrow.utcnow().replace(hours=-2) >>> earlier.humanize() '2 hours ago' >>> later = later = earlier.replace(hours=4) >>> later.humanize(earlier) 'in 4 hours' ''' locale = locales.get_locale(locale) if other is None: utc = datetime.utcnow().replace(tzinfo=dateutil_tz.tzutc()) dt = utc.astimezone(self._datetime.tzinfo) elif isinstance(other, Arrow): dt = other._datetime elif isinstance(other, datetime): if other.tzinfo is None: dt = other.replace(tzinfo=self._datetime.tzinfo) else: dt = other.astimezone(self._datetime.tzinfo) else: raise TypeError() delta = int(util.total_seconds(self._datetime - dt)) sign = -1 if delta < 0 else 1 diff = abs(delta) delta = diff if diff < 10: return locale.describe('now', only_distance=only_distance) if diff < 45: return locale.describe('seconds', sign, only_distance=only_distance) elif diff < 90: return locale.describe('minute', sign, only_distance=only_distance) elif diff < 2700: minutes = sign * int(max(delta / 60, 2)) return locale.describe('minutes', minutes, only_distance=only_distance) elif diff < 5400: return locale.describe('hour', sign, only_distance=only_distance) elif diff < 79200: hours = sign * int(max(delta / 3600, 2)) return locale.describe('hours', hours, only_distance=only_distance) elif diff < 129600: return locale.describe('day', sign, only_distance=only_distance) elif diff < 2160000: days = sign * int(max(delta / 86400, 2)) return locale.describe('days', days, only_distance=only_distance) elif diff < 3888000: return locale.describe('month', sign, only_distance=only_distance) elif diff < 29808000: self_months = self._datetime.year * 12 + self._datetime.month other_months = dt.year * 12 + dt.month months = sign * int(max(abs(other_months - self_months), 2)) return locale.describe('months', months, only_distance=only_distance) elif diff < 47260800: return locale.describe('year', sign, only_distance=only_distance) else: years = sign * int(max(delta / 31536000, 2)) return locale.describe('years', years, only_distance=only_distance)
def __init__(self, locale: str = "en_us") -> None: self.locale = locales.get_locale(locale)
def __init__(self, locale="en_us"): self.locale = locales.get_locale(locale)
def humanize(self, other=None, locale='en_us'): ''' Returns a localized, humanized representation of a relative difference in time. :param other: (optional) an :class:`Arrow <arrow.arrow.Arrow>` or ``datetime`` object. Defaults to now in the current :class:`Arrow <arrow.arrow.Arrow>` objet's timezone. :param locale: (optional) a ``str`` specifying a locale. Defaults to 'en_us'. Usage:: >>> earlier = arrow.utcnow().replace(hours=-2) >>> earlier.humanize() '2 hours ago' >>> later = later = earlier.replace(hours=4) >>> later.humanize(earlier) 'in 4 hours' ''' locale = locales.get_locale(locale) if other is None: utc = datetime.utcnow().replace(tzinfo=dateutil_tz.tzutc()) dt = utc.astimezone(self._datetime.tzinfo) elif isinstance(other, Arrow): dt = other._datetime elif isinstance(other, datetime): if other.tzinfo is None: dt = other.replace(tzinfo=self._datetime.tzinfo) else: dt = other.astimezone(self._datetime.tzinfo) else: raise TypeError() delta = int(util.total_seconds(self._datetime - dt)) sign = -1 if delta < 0 else 1 diff = abs(delta) delta = diff if diff < 10: return locale.describe('now') if diff < 45: return locale.describe('seconds', sign) elif diff < 90: return locale.describe('minute', sign) elif diff < 2700: minutes = sign * int(max(delta / 60, 2)) return locale.describe('minutes', minutes) elif diff < 5400: return locale.describe('hour', sign) elif diff < 79200: hours = sign * int(max(delta / 3600, 2)) return locale.describe('hours', hours) elif diff < 129600: return locale.describe('day', sign) elif diff < 2160000: days = sign * int(max(delta / 86400, 2)) return locale.describe('days', days) elif diff < 3888000: return locale.describe('month', sign) elif diff < 29808000: self_months = self._datetime.year * 12 + self._datetime.month other_months = dt.year * 12 + dt.month months = sign * abs(other_months - self_months) return locale.describe('months', months) elif diff < 47260800: return locale.describe('year', sign) else: years = sign * int(max(delta / 31536000, 2)) return locale.describe('years', years)
def humanize(self, other=None, locale="en_us", only_distance=False, granularity="auto"): """ Returns a localized, humanized representation of a relative difference in time. :param other: (optional) an :class:`Arrow <arrow.arrow.Arrow>` or ``datetime`` object. Defaults to now in the current :class:`Arrow <arrow.arrow.Arrow>` object's timezone. :param locale: (optional) a ``str`` specifying a locale. Defaults to 'en_us'. :param only_distance: (optional) returns only time difference eg: "11 seconds" without "in" or "ago" part. :param granularity: (optional) defines the precision of the output. Set it to strings 'second', 'minute', 'hour', 'day', 'week', 'month' or 'year' or a list of any combination of these strings Usage:: >>> earlier = arrow.utcnow().shift(hours=-2) >>> earlier.humanize() '2 hours ago' >>> later = earlier.shift(hours=4) >>> later.humanize(earlier) 'in 4 hours' """ locale_name = locale locale = locales.get_locale(locale) if other is None: utc = datetime.utcnow().replace(tzinfo=dateutil_tz.tzutc()) dt = utc.astimezone(self._datetime.tzinfo) elif isinstance(other, Arrow): dt = other._datetime elif isinstance(other, datetime): if other.tzinfo is None: dt = other.replace(tzinfo=self._datetime.tzinfo) else: dt = other.astimezone(self._datetime.tzinfo) else: raise TypeError( "Invalid 'other' argument of type '{}'. " "Argument must be of type None, Arrow, or datetime.".format( type(other).__name__)) if isinstance(granularity, list) and len(granularity) == 1: granularity = granularity[0] delta = int(round(util.total_seconds(self._datetime - dt))) sign = -1 if delta < 0 else 1 diff = abs(delta) delta = diff try: if granularity == "auto": if diff < 10: return locale.describe("now", only_distance=only_distance) if diff < 45: seconds = sign * delta return locale.describe("seconds", seconds, only_distance=only_distance) elif diff < 90: return locale.describe("minute", sign, only_distance=only_distance) elif diff < 2700: minutes = sign * int(max(delta / 60, 2)) return locale.describe("minutes", minutes, only_distance=only_distance) elif diff < 5400: return locale.describe("hour", sign, only_distance=only_distance) elif diff < 79200: hours = sign * int(max(delta / 3600, 2)) return locale.describe("hours", hours, only_distance=only_distance) # anything less than 48 hours should be 1 day elif diff < 172800: return locale.describe("day", sign, only_distance=only_distance) elif diff < 554400: days = sign * int(max(delta / 86400, 2)) return locale.describe("days", days, only_distance=only_distance) elif diff < 907200: return locale.describe("week", sign, only_distance=only_distance) elif diff < 2419200: weeks = sign * int(max(delta / 604800, 2)) return locale.describe("weeks", weeks, only_distance=only_distance) elif diff < 3888000: return locale.describe("month", sign, only_distance=only_distance) elif diff < 29808000: self_months = self._datetime.year * 12 + self._datetime.month other_months = dt.year * 12 + dt.month months = sign * int(max(abs(other_months - self_months), 2)) return locale.describe("months", months, only_distance=only_distance) elif diff < 47260800: return locale.describe("year", sign, only_distance=only_distance) else: years = sign * int(max(delta / 31536000, 2)) return locale.describe("years", years, only_distance=only_distance) elif util.isstr(granularity): if granularity == "second": delta = sign * delta if abs(delta) < 2: return locale.describe("now", only_distance=only_distance) elif granularity == "minute": delta = sign * delta / self._SECS_PER_MINUTE elif granularity == "hour": delta = sign * delta / self._SECS_PER_HOUR elif granularity == "day": delta = sign * delta / self._SECS_PER_DAY elif granularity == "week": delta = sign * delta / self._SECS_PER_WEEK elif granularity == "month": delta = sign * delta / self._SECS_PER_MONTH elif granularity == "year": delta = sign * delta / self._SECS_PER_YEAR else: raise AttributeError( "Invalid level of granularity. Please select between 'second', 'minute', 'hour', 'day', 'week', 'month' or 'year'" ) if trunc(abs(delta)) != 1: granularity += "s" return locale.describe(granularity, delta, only_distance=only_distance) else: timeframes = [] if "year" in granularity: years = sign * delta / self._SECS_PER_YEAR delta %= self._SECS_PER_YEAR timeframes.append(["year", years]) if "month" in granularity: months = sign * delta / self._SECS_PER_MONTH delta %= self._SECS_PER_MONTH timeframes.append(["month", months]) if "week" in granularity: weeks = sign * delta / self._SECS_PER_WEEK delta %= self._SECS_PER_WEEK timeframes.append(["week", weeks]) if "day" in granularity: days = sign * delta / self._SECS_PER_DAY delta %= self._SECS_PER_DAY timeframes.append(["day", days]) if "hour" in granularity: hours = sign * delta / self._SECS_PER_HOUR delta %= self._SECS_PER_HOUR timeframes.append(["hour", hours]) if "minute" in granularity: minutes = sign * delta / self._SECS_PER_MINUTE delta %= self._SECS_PER_MINUTE timeframes.append(["minute", minutes]) if "second" in granularity: seconds = sign * delta timeframes.append(["second", seconds]) if len(timeframes) < len(granularity): raise AttributeError( "Invalid level of granularity. " "Please select between 'second', 'minute', 'hour', 'day', 'week', 'month' or 'year'." ) for tf in timeframes: # Make granularity plural if the delta is not equal to 1 if trunc(abs(tf[1])) != 1: tf[0] += "s" return locale.describe_multi(timeframes, only_distance=only_distance) except KeyError as e: raise ValueError( "Humanization of the {} granularity is not currently translated in the '{}' locale. " "Please consider making a contribution to this locale.".format( e, locale_name))
def format(dt, str_format, locale='en_us'): locale = locales.get_locale(locale) FORMAT_RE = re.compile('(YYY?Y?|MM?M?M?|Do|DD?D?D?|d?dd?d?|HH?|hh?|mm?|ss?|SS?S?S?S?S?|ZZ?|a|A|X)') return FORMAT_RE.sub(lambda m: format_token(dt, m.group(0), locale), str_format)
def format_token_en_us(dt, str_format): locale = locales.get_locale('en_us') return formatter.format_token(dt, str_format, locale)
def humanize(self, other=None, locale='en_us', only_distance=False, granularity='auto'): ''' Returns a localized, humanized representation of a relative difference in time. :param other: (optional) an :class:`Arrow <arrow.arrow.Arrow>` or ``datetime`` object. Defaults to now in the current :class:`Arrow <arrow.arrow.Arrow>` object's timezone. :param locale: (optional) a ``str`` specifying a locale. Defaults to 'en_us'. :param only_distance: (optional) returns only time difference eg: "11 seconds" without "in" or "ago" part. :param granularity: (optional) defines the precision of the output. Set it to strings 'second', 'minute', 'hour', 'day', 'month' or 'year'. Usage:: >>> earlier = arrow.utcnow().shift(hours=-2) >>> earlier.humanize() '2 hours ago' >>> later = later = earlier.shift(hours=4) >>> later.humanize(earlier) 'in 4 hours' ''' locale = locales.get_locale(locale) if other is None: utc = datetime.utcnow().replace(tzinfo=dateutil_tz.tzutc()) dt = utc.astimezone(self._datetime.tzinfo) elif isinstance(other, Arrow): dt = other._datetime elif isinstance(other, datetime): if other.tzinfo is None: dt = other.replace(tzinfo=self._datetime.tzinfo) else: dt = other.astimezone(self._datetime.tzinfo) else: raise TypeError() delta = int(util.total_seconds(self._datetime - dt)) sign = -1 if delta < 0 else 1 diff = abs(delta) delta = diff if granularity == 'auto': if diff < 10: return locale.describe('now', only_distance=only_distance) if diff < 45: seconds = sign * delta return locale.describe('seconds', seconds, only_distance=only_distance) elif diff < 90: return locale.describe('minute', sign, only_distance=only_distance) elif diff < 2700: minutes = sign * int(max(delta / 60, 2)) return locale.describe('minutes', minutes, only_distance=only_distance) elif diff < 5400: return locale.describe('hour', sign, only_distance=only_distance) elif diff < 79200: hours = sign * int(max(delta / 3600, 2)) return locale.describe('hours', hours, only_distance=only_distance) elif diff < 129600: return locale.describe('day', sign, only_distance=only_distance) elif diff < 2160000: days = sign * int(max(delta / 86400, 2)) return locale.describe('days', days, only_distance=only_distance) elif diff < 3888000: return locale.describe('month', sign, only_distance=only_distance) elif diff < 29808000: self_months = self._datetime.year * 12 + self._datetime.month other_months = dt.year * 12 + dt.month months = sign * int(max(abs(other_months - self_months), 2)) return locale.describe('months', months, only_distance=only_distance) elif diff < 47260800: return locale.describe('year', sign, only_distance=only_distance) else: years = sign * int(max(delta / 31536000, 2)) return locale.describe('years', years, only_distance=only_distance) else: if granularity == 'second': delta = sign * delta if (abs(delta) < 2): return locale.describe('now', only_distance=only_distance) elif granularity == 'minute': delta = sign * delta / float(60) elif granularity == 'hour': delta = sign * delta / float(60 * 60) elif granularity == 'day': delta = sign * delta / float(60 * 60 * 24) elif granularity == 'month': delta = sign * delta / float(60 * 60 * 24 * 30.5) elif granularity == 'year': delta = sign * delta / float(60 * 60 * 24 * 365.25) else: raise AttributeError( 'Error. Could not understand your level of granularity. Please select between \ "second", "minute", "hour", "day", "week", "month" or "year"') if (trunc(abs(delta)) != 1): granularity += 's' return locale.describe(granularity, delta, only_distance=only_distance)
def humanize(self, other=None, locale="en_us", only_distance=False, granularity="auto"): """ Returns a localized, humanized representation of a relative difference in time. :param other: (optional) an :class:`Arrow <arrow.arrow.Arrow>` or ``datetime`` object. Defaults to now in the current :class:`Arrow <arrow.arrow.Arrow>` object's timezone. :param locale: (optional) a ``str`` specifying a locale. Defaults to 'en_us'. :param only_distance: (optional) returns only time difference eg: "11 seconds" without "in" or "ago" part. :param granularity: (optional) defines the precision of the output. Set it to strings 'second', 'minute', 'hour', 'day', 'week', 'month' or 'year'. Usage:: >>> earlier = arrow.utcnow().shift(hours=-2) >>> earlier.humanize() '2 hours ago' >>> later = earlier.shift(hours=4) >>> later.humanize(earlier) 'in 4 hours' """ locale_name = locale locale = locales.get_locale(locale) if other is None: utc = datetime.utcnow().replace(tzinfo=dateutil_tz.tzutc()) dt = utc.astimezone(self._datetime.tzinfo) elif isinstance(other, Arrow): dt = other._datetime elif isinstance(other, datetime): if other.tzinfo is None: dt = other.replace(tzinfo=self._datetime.tzinfo) else: dt = other.astimezone(self._datetime.tzinfo) else: raise TypeError() delta = int(round(util.total_seconds(self._datetime - dt))) sign = -1 if delta < 0 else 1 diff = abs(delta) delta = diff try: if granularity == "auto": if diff < 10: return locale.describe("now", only_distance=only_distance) if diff < 45: seconds = sign * delta return locale.describe("seconds", seconds, only_distance=only_distance) elif diff < 90: return locale.describe("minute", sign, only_distance=only_distance) elif diff < 2700: minutes = sign * int(max(delta / 60, 2)) return locale.describe("minutes", minutes, only_distance=only_distance) elif diff < 5400: return locale.describe("hour", sign, only_distance=only_distance) elif diff < 79200: hours = sign * int(max(delta / 3600, 2)) return locale.describe("hours", hours, only_distance=only_distance) elif diff < 129600: return locale.describe("day", sign, only_distance=only_distance) elif diff < 554400: days = sign * int(max(delta / 86400, 2)) return locale.describe("days", days, only_distance=only_distance) elif diff < 907200: return locale.describe("week", sign, only_distance=only_distance) elif diff < 2419200: weeks = sign * int(max(delta / 604800, 2)) return locale.describe("weeks", weeks, only_distance=only_distance) elif diff < 3888000: return locale.describe("month", sign, only_distance=only_distance) elif diff < 29808000: self_months = self._datetime.year * 12 + self._datetime.month other_months = dt.year * 12 + dt.month months = sign * int(max(abs(other_months - self_months), 2)) return locale.describe("months", months, only_distance=only_distance) elif diff < 47260800: return locale.describe("year", sign, only_distance=only_distance) else: years = sign * int(max(delta / 31536000, 2)) return locale.describe("years", years, only_distance=only_distance) else: if granularity == "second": delta = sign * delta if abs(delta) < 2: return locale.describe("now", only_distance=only_distance) elif granularity == "minute": delta = sign * delta / float(60) elif granularity == "hour": delta = sign * delta / float(60 * 60) elif granularity == "day": delta = sign * delta / float(60 * 60 * 24) elif granularity == "week": delta = sign * delta / float(60 * 60 * 24 * 7) elif granularity == "month": delta = sign * delta / float(60 * 60 * 24 * 30.5) elif granularity == "year": delta = sign * delta / float(60 * 60 * 24 * 365.25) else: raise AttributeError( "Invalid level of granularity. Please select between 'second', 'minute', 'hour', 'day', 'week', 'month' or 'year'" ) if trunc(abs(delta)) != 1: granularity += "s" return locale.describe(granularity, delta, only_distance=only_distance) except KeyError as e: raise ValueError( "Humanization of the {} granularity is not currently translated in the '{}' locale. Please consider making a contribution to this locale." .format(e, locale_name))
def humanize(self, other=None, locale='en_us', only_distance=False, granularity='auto'): ''' Returns a localized, humanized representation of a relative difference in time. :param other: (optional) an :class:`Arrow <arrow.arrow.Arrow>` or ``datetime`` object. Defaults to now in the current :class:`Arrow <arrow.arrow.Arrow>` object's timezone. :param locale: (optional) a ``str`` specifying a locale. Defaults to 'en_us'. :param only_distance: (optional) returns only time difference eg: "11 seconds" without "in" or "ago" part. :param granularity: (optional) defines the precision of the output. Set it to strings 'second', 'minute', 'hour', 'day', 'month' or 'year'. Usage:: >>> earlier = arrow.utcnow().shift(hours=-2) >>> earlier.humanize() '2 hours ago' >>> later = later = earlier.shift(hours=4) >>> later.humanize(earlier) 'in 4 hours' ''' locale = locales.get_locale(locale) if other is None: utc = datetime.utcnow().replace(tzinfo=dateutil_tz.tzutc()) dt = utc.astimezone(self._datetime.tzinfo) elif isinstance(other, Arrow): dt = other._datetime elif isinstance(other, datetime): if other.tzinfo is None: dt = other.replace(tzinfo=self._datetime.tzinfo) else: dt = other.astimezone(self._datetime.tzinfo) else: raise TypeError() delta = int(util.total_seconds(self._datetime - dt)) sign = -1 if delta < 0 else 1 diff = abs(delta) delta = diff if granularity=='auto': if diff < 10: return locale.describe('now', only_distance=only_distance) if diff < 45: seconds = sign * delta return locale.describe('seconds', seconds, only_distance=only_distance) elif diff < 90: return locale.describe('minute', sign, only_distance=only_distance) elif diff < 2700: minutes = sign * int(max(delta / 60, 2)) return locale.describe('minutes', minutes, only_distance=only_distance) elif diff < 5400: return locale.describe('hour', sign, only_distance=only_distance) elif diff < 79200: hours = sign * int(max(delta / 3600, 2)) return locale.describe('hours', hours, only_distance=only_distance) elif diff < 129600: return locale.describe('day', sign, only_distance=only_distance) elif diff < 2160000: days = sign * int(max(delta / 86400, 2)) return locale.describe('days', days, only_distance=only_distance) elif diff < 3888000: return locale.describe('month', sign, only_distance=only_distance) elif diff < 29808000: self_months = self._datetime.year * 12 + self._datetime.month other_months = dt.year * 12 + dt.month months = sign * int(max(abs(other_months - self_months), 2)) return locale.describe('months', months, only_distance=only_distance) elif diff < 47260800: return locale.describe('year', sign, only_distance=only_distance) else: years = sign * int(max(delta / 31536000, 2)) return locale.describe('years', years, only_distance=only_distance) else: if granularity == 'second': delta = sign * delta if(abs(delta) < 2): return locale.describe('now', only_distance=only_distance) elif granularity == 'minute': delta = sign * delta / float(60) elif granularity == 'hour': delta = sign * delta / float(60*60) elif granularity == 'day': delta = sign * delta / float(60*60*24) elif granularity == 'month': delta = sign * delta / float(60*60*24*30.5) elif granularity == 'year': delta = sign * delta / float(60*60*24*365.25) else: raise AttributeError('Error. Could not understand your level of granularity. Please select between \ "second", "minute", "hour", "day", "week", "month" or "year"') if(trunc(abs(delta)) != 1): granularity += 's' return locale.describe(granularity, delta, only_distance=only_distance)
def __init__(self, locale: str = DEFAULT_LOCALE) -> None: self.locale = locales.get_locale(locale)
def humanize(self): ''' Returns a localized, humanized representation of a relative difference in time. :param locale: (optional) a ``str`` specifying a locale. Defaults to 'en_us'. :param only_distance: (optional) returns only time difference eg: "11 seconds" without "in" or "ago" part. :param granularity: (optional) defines the precision of the output. Set it to strings 'second', 'minute', 'hour', 'day', 'month' or 'year'. Usage:: >>> earlier = arrow.utcnow().shift(hours=-2) >>> earlier.humanize() '2 hours ago' >>> later = later = earlier.shift(hours=4) >>> later.humanize(earlier) 'in 4 hours' ''' locale = locales.get_locale('en_us') utc = datetime.utcnow().replace(tzinfo=dateutil_tz.tzutc()) dt = utc.astimezone(self._datetime.tzinfo) delta = int(util.total_seconds(self._datetime - dt)) sign = -1 if delta < 0 else 1 diff = abs(delta) delta = diff if diff < 10: return locale.describe('now') if diff < 45: seconds = sign * delta return locale.describe('seconds', seconds) elif diff < 90: return locale.describe('minute', sign) elif diff < 2700: minutes = sign * int(max(delta / 60, 2)) return locale.describe('minutes', minutes) elif diff < 5400: return locale.describe('hour', sign) elif diff < 79200: hours = sign * int(max(delta / 3600, 2)) return locale.describe('hours', hours) elif diff < 129600: return locale.describe('day', sign) elif diff < 2160000: days = sign * int(max(delta / 86400, 2)) return locale.describe('days', days) elif diff < 3888000: return locale.describe('month', sign) elif diff < 29808000: self_months = self._datetime.year * 12 + self._datetime.month other_months = dt.year * 12 + dt.month months = sign * int(max(abs(other_months - self_months), 2)) return locale.describe('months', months) elif diff < 47260800: return locale.describe('year', sign) else: years = sign * int(max(delta / 31536000, 2)) return locale.describe('years', years)