Python第三方库arrow
简介
-
处理时间日期的一个第三方库
-
Arrow is a Python library that offers a sensible and human-friendly approach to creating, manipulating, formatting and converting dates, times and timestamps. It implements and updates the datetime type, plugging gaps in functionality and providing an intelligent module API that supports many common creation scenarios. Simply put, it helps you work with dates and times with fewer imports and a lot less code.
优点
-
Too many modules: datetime, time, calendar, dateutil, pytz and more
-
Too many types: date, time, datetime, tzinfo, timedelta, relativedelta, etc.
-
Timezones and timestamp conversions are verbose and unpleasant
-
Timezone naivety is the norm
-
Gaps in functionality: ISO 8601 parsing, timespans, humanization
特性
-
Fully-implemented, drop-in replacement for datetime
-
Support for Python 3.6+
-
Timezone-aware and UTC by default
-
Super-simple creation options for many common input scenarios
-
shift
method with support for relative offsets, including weeks -
Format and parse strings automatically
-
Wide support for the ISO 8601 standard
-
Timezone conversion
-
Support for
dateutil
,pytz
, andZoneInfo
tzinfo objects -
Generates time spans, ranges, floors and ceilings for time frames ranging from microsecond to year
-
Humanize dates and times with a growing list of contributed locales
-
Extensible for your own Arrow-derived types
-
Full support for PEP 484-style type hints
官方示例
稍作补充
>>> import arrow
>>> arrow.get('2013-05-11T21:23:58.970460+07:00')
<Arrow [2013-05-11T21:23:58.970460+07:00]>
>>> utc = arrow.utcnow()
>>> utc
<Arrow [2013-05-11T21:23:58.970460+00:00]>
>>> now = arrow.now() #当前时间
>>> now
<Arrow [2022-03-31T11:06:21.477106+08:00]>
>>> utc = utc.shift(hours=-1) #偏移,前面1个小时
>>> utc
<Arrow [2013-05-11T20:23:58.970460+00:00]>
>>> local = utc.to('US/Pacific')
>>> local
<Arrow [2013-05-11T13:23:58.970460-07:00]>
>>> local.timestamp()
1368303838.970460
>>> local.format() #时间格式化
'2013-05-11 13:23:58 -07:00'
>>> local.format('YYYY-MM-DD HH:mm:ss ZZ')
'2013-05-11 13:23:58 -07:00'
>>> local.humanize() #人性化输出
'an hour ago'
>>> local.humanize(locale='ko-kr')
'한시간 전'
引申
关于时间偏移shift
-
源码部分
def shift(self, **kwargs: Any) -> "Arrow":
relative_kwargs = {}
additional_attrs = ["weeks", "quarters", "weekday"]
for key, value in kwargs.items():
if key in self._ATTRS_PLURAL or key in additional_attrs:
relative_kwargs[key] = value
else:
supported_attr = ", ".join(self._ATTRS_PLURAL + additional_attrs)
raise ValueError(
f"Invalid shift time frame. Please select one of the following: {supported_attr}."
)
_ATTRS: Final[List[str]] = [
"year",
"month",
"day",
"hour",
"minute",
"second",
"microsecond",
]
_ATTRS_PLURAL: Final[List[str]] = [f"{a}s" for a in _ATTRS]
additional_attrs = ["weeks", "quarters", "weekday"]-
测试代码
import arrow
now = arrow.now()
now.shift(fenzhong=1) #这是不支持的,支持的如下提示ValueError: Invalid shift time frame. Please select one of the following: years, months, days, hours, minutes, seconds, microseconds, weeks, quarters, weekday.
-
示例代码:对shift的weeks和weekday的说明,其他的几个参数都比较简单
import arrow
now = arrow.now()
print(now.format('YYYY-MM-DD')) #当前时间 2022-03-31
print(now.shift(weeks=1)) #1周后 #2022-04-07T11:22:56.715460+08:00
print(now.shift(weekday=1)) #最近的周二 #2022-04-05T11:22:56.715460+08:00-
weekday的取值范围是0~6,0代表周1,6代表周日,依次类推。
-
-
关于时间格式化format
-
源码
def _format_token(self, dt: datetime, token: Optional[str]) -> Optional[str]:
if token and token.startswith("[") and token.endswith("]"):
return token[1:-1]
if token == "YYYY":
return self.locale.year_full(dt.year)
if token == "YY":
return self.locale.year_abbreviation(dt.year)
if token == "MMMM":
return self.locale.month_name(dt.month)
if token == "MMM":
return self.locale.month_abbreviation(dt.month)
if token == "MM":
return f"{dt.month:02d}"
if token == "M":
return f"{dt.month}"
if token == "DDDD":
return f"{dt.timetuple().tm_yday:03d}"
if token == "DDD":
return f"{dt.timetuple().tm_yday}"
if token == "DD":
return f"{dt.day:02d}"
if token == "D":
return f"{dt.day}"
if token == "Do":
return self.locale.ordinal_number(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 f"{dt.isoweekday()}"
if token == "HH":
return f"{dt.hour:02d}"
if token == "H":
return f"{dt.hour}"
if token == "hh":
return f"{dt.hour if 0 < dt.hour < 13 else abs(dt.hour - 12):02d}"
if token == "h":
return f"{dt.hour if 0 < dt.hour < 13 else abs(dt.hour - 12)}"
if token == "mm":
return f"{dt.minute:02d}"
if token == "m":
return f"{dt.minute}"
if token == "ss":
return f"{dt.second:02d}"
if token == "s":
return f"{dt.second}"
if token == "SSSSSS":
return f"{dt.microsecond:06d}"
if token == "SSSSS":
return f"{dt.microsecond // 10:05d}"
if token == "SSSS":
return f"{dt.microsecond // 100:04d}"
if token == "SSS":
return f"{dt.microsecond // 1000:03d}"
if token == "SS":
return f"{dt.microsecond // 10000:02d}"
if token == "S":
return f"{dt.microsecond // 100000}"
if token == "X":
return f"{dt.timestamp()}"
if token == "x":
return f"{dt.timestamp() * 1_000_000:.0f}"
if token == "ZZZ":
return dt.tzname()
if token in ["ZZ", "Z"]:
separator = ":" if token == "ZZ" else ""
tz = dateutil_tz.tzutc() if dt.tzinfo is None else dt.tzinfo
# `dt` must be aware object. Otherwise, this line will raise AttributeError
# https://github.com/arrow-py/arrow/pull/883#discussion_r529866834
# datetime awareness: https://docs.python.org/3/library/datetime.html#aware-and-naive-objects
total_minutes = int(cast(timedelta, tz.utcoffset(dt)).total_seconds() / 60)
sign = "+" if total_minutes >= 0 else "-"
total_minutes = abs(total_minutes)
hour, minute = divmod(total_minutes, 60)
return f"{sign}{hour:02d}{separator}{minute:02d}"
if token in ("a", "A"):
return self.locale.meridian(dt.hour, token)
if token == "W":
year, week, day = dt.isocalendar()
return f"{year}-W{week:02d}-{day}"
-
示例代码
import arrow
now = arrow.now()
print(now) #2022-03-31T11:47:45.684950+08:00
print(now.format('YYYY')) #四位的年 2022
print(now.format('YY')) #两位的年 22
print(now.format('MMMM')) #月份英文全拼 March
print(now.format('MMM')) #月份简写 Mar
print(now.format('MM')) #03
print(now.format('M')) #3
print(now.format('DDDD')) #090 这是啥?
print(now.format('DDD')) #90
print(now.format('DD')) #31
print(now.format('D')) #31
print(now.format('dddd')) #Thursday
print(now.format('ddd')) #Thu
print(now.format('HH')) #11
print(now.format('H')) #11
print(now.format('hh')) #11
print(now.format('h')) #11
print(now.format('mm')) #47
print(now.format('m')) #47
print(now.format('ss')) #45
print(now.format('s')) #45
print(now.format('SSSSSS')) #684950
print(now.format('SSSSS')) #68495
print(now.format('SSSS')) #6849
print(now.format('SSS')) #684
print(now.format('SS')) #68
print(now.format('S')) #6
print(now.format('X')) #1648698465.68495
print(now.format('x')) #1648698465684950
print(now.format('ZZZ')) #中国标准时间
print(now.format('ZZ')) #+08:00
print(now.format('Z')) #+0800
print(now.format('a')) #am
print(now.format('A')) #AM
print(now.format('W')) #2022-W13-4 -
补充
print(now.weekday()) #输出当前周几
-
关于人性化humanize
-
示例代码
import arrow
now = arrow.now()
past = now.shift(hours=-1)
print(past.humanize()) #an hour ago
furture = now.shift(hours=1)
print(furture.humanize()) #in an hour
其他实例(属性、时间戳、替换)
-
示例代码
import arrow
now = arrow.now()
print(now) #2022-03-31T13:40:13.711922+08:00
print(now.year)
print(now.month)
print(now.day)
print(now.hour)
print(now.minute)
print(now.second)
print(now.microsecond)
print(now.timestamp()) #1648705213.711922
print(now.int_timestamp) #时间戳的整数部分 1648705213 -
对于时间戳,可以通过get反过来获取时间
import arrow
time1 = arrow.get(1648705213) #注意不能使用引号
print(time1.year) -
计算毫秒的一个示例
import arrow
t1 = arrow.now().timestamp()
from time import sleep
sleep(2)
t2 = arrow.now().timestamp()
print(int(round(t2-t1,3))*1000) -
替换时间
import arrow
t1 = arrow.now()
print(t1)
t2 = t1.replace(year=2018) #替换个年份
print(t2)
t3 = t1.replace(month=11,day=14) #替换月和日
print(t3)