def parse(cls, string): tzinfo = None if string == 'local': tzinfo = tz.tzlocal() elif string in ['utc', 'UTC']: tzinfo = tz.tzutc() else: iso_match = cls._TZINFO_RE.match(string) if iso_match: sign, hours, minutes = iso_match.groups() seconds = int(hours) * 3600 + int(minutes) * 60 if sign == '-': seconds *= -1 tzinfo = tz.tzoffset(None, seconds) else: tzinfo = tz.gettz(string) if tzinfo is None: raise ParserError('Could not parse timezone expression "{0}"', string) return tzinfo
def utcnow(cls): ''' Constructs an :class:`Arrow <arrow.arrow.Arrow>` object, representing "now" in UTC time. ''' dt = datetime.utcnow() return cls(dt.year, dt.month, dt.day, dt.hour, dt.minute, dt.second, dt.microsecond, dateutil_tz.tzutc())
def fromdate(cls, date, tzinfo=None): ''' Constructs an :class:`Arrow <arrow.arrow.Arrow>` object from a ``date`` and optional ``tzinfo`` object. Time values are set to 0. :param date: the ``date`` :param tzinfo: (optional) a ``tzinfo`` object. Defaults to UTC. ''' tzinfo = tzinfo or dateutil_tz.tzutc() return cls(date.year, date.month, date.day, tzinfo=tzinfo)
def _get_tzinfo(cls, tz_expr): if tz_expr is None: return dateutil_tz.tzutc() if isinstance(tz_expr, tzinfo): return tz_expr else: try: return parser.TzinfoParser.parse(tz_expr) except parser.ParserError: raise ValueError('\'{0}\' not recognized as a timezone')
def utcfromtimestamp(cls, timestamp): '''Constructs an :class:`Arrow <arrow.arrow.Arrow>` object from a timestamp, in UTC time. :param timestamp: an ``int`` or ``float`` timestamp, or a ``str`` that converts to either. ''' timestamp = cls._get_timestamp_from_input(timestamp) dt = datetime.utcfromtimestamp(timestamp) return cls(dt.year, dt.month, dt.day, dt.hour, dt.minute, dt.second, dt.microsecond, dateutil_tz.tzutc())
def now(cls, tzinfo=None): '''Constructs an :class:`Arrow <arrow.arrow.Arrow>` object, representing "now". :param tzinfo: (optional) a ``tzinfo`` object. Defaults to local time. ''' utc = datetime.utcnow().replace(tzinfo=dateutil_tz.tzutc()) dt = utc.astimezone( dateutil_tz.tzlocal() if tzinfo is None else tzinfo) return cls(dt.year, dt.month, dt.day, dt.hour, dt.minute, dt.second, dt.microsecond, dt.tzinfo)
def fromdatetime(cls, dt, tzinfo=None): ''' Constructs an :class:`Arrow <arrow.arrow.Arrow>` object from a ``datetime`` and optional ``tzinfo`` object. :param dt: the ``datetime`` :param tzinfo: (optional) a ``tzinfo`` object. Defaults to UTC. ''' tzinfo = tzinfo or dt.tzinfo or dateutil_tz.tzutc() return cls(dt.year, dt.month, dt.day, dt.hour, dt.minute, dt.second, dt.microsecond, tzinfo)
def __init__(self, year, month, day, hour=0, minute=0, second=0, microsecond=0, tzinfo=None): if util.isstr(tzinfo): tzinfo = parser.TzinfoParser.parse(tzinfo) tzinfo = tzinfo or dateutil_tz.tzutc() self._datetime = datetime(year, month, day, hour, minute, second, microsecond, tzinfo)
def _build_datetime(cls, parts): timestamp = parts.get('timestamp') if timestamp: tz_utc = tz.tzutc() return datetime.fromtimestamp(timestamp, tz=tz_utc) am_pm = parts.get('am_pm') hour = parts.get('hour', 0) if am_pm == 'pm' and hour < 12: hour += 12 elif am_pm == 'am' and hour == 12: hour = 0 return datetime(year=parts.get('year', 1), month=parts.get('month', 1), day=parts.get('day', 1), hour=hour, minute=parts.get('minute', 0), second=parts.get('second', 0), microsecond=parts.get('microsecond', 0), tzinfo=parts.get('tzinfo'))
def _format_token(self, dt, token): if token == 'YYYY': return '{0:04d}'.format(dt.year) if token == 'YY': return '{0:04d}'.format(dt.year)[2:] if token == 'MMMM': return self.locale.month_name(dt.month) if token == 'MMM': return self.locale.month_abbreviation(dt.month) if token == 'MM': return '{0:02d}'.format(dt.month) if token == 'M': return str(dt.month) if token == 'DDDD': return '{0:03d}'.format(dt.timetuple().tm_yday) if token == 'DDD': return str(dt.timetuple().tm_yday) if token == 'DD': return '{0:02d}'.format(dt.day) if token == 'D': return str(dt.day) if token == 'dddd': return self.locale.day_name(dt.isoweekday()) if token == 'ddd': return self.locale.day_abbreviation(dt.isoweekday()) if token == 'd': return str(dt.isoweekday()) if token == 'HH': return '{0:02d}'.format(dt.hour) if token == 'H': return str(dt.hour) if token == 'hh': return '{0:02d}'.format( dt.hour if 0 < dt.hour < 13 else abs(dt.hour - 12)) if token == 'h': return str(dt.hour if 0 < dt.hour < 13 else abs(dt.hour - 12)) if token == 'mm': return '{0:02d}'.format(dt.minute) if token == 'm': return str(dt.minute) if token == 'ss': return '{0:02d}'.format(dt.second) if token == 's': return str(dt.second) if token == 'SSSSSS': return str('{0:06d}'.format(int(dt.microsecond))) if token == 'SSSSS': return str('{0:05d}'.format(int(dt.microsecond / 10))) if token == 'SSSS': return str('{0:04d}'.format(int(dt.microsecond / 100))) if token == 'SSS': return str('{0:03d}'.format(int(dt.microsecond / 1000))) if token == 'SS': return str('{0:02d}'.format(int(dt.microsecond / 10000))) if token == 'S': return str(int(dt.microsecond / 100000)) if token == 'X': return str(calendar.timegm(dt.utctimetuple())) if token in ['ZZ', 'Z']: separator = ':' if token == 'ZZ' else '' tz = dateutil_tz.tzutc() if dt.tzinfo is None else dt.tzinfo total_minutes = int(util.total_seconds(tz.utcoffset(dt)) / 60) sign = '+' if total_minutes > 0 else '-' total_minutes = abs(total_minutes) hour, minute = divmod(total_minutes, 60) return '{0}{1:02d}{2}{3:02d}'.format(sign, hour, separator, minute) if token in ('a', 'A'): return self.locale.meridian(dt.hour, token)
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>` object'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)