Skip to content

arrow

Arrow是一个人性化的创建、操作、格式化和转换日期时间的 Python 库。

Note

实际上 Python 标准库提供了完整的日期、时间和时区功能。但是它最初的架构设计非常差导致不断引入了太多的模块和类型。

创建: 通过工厂函数实现

Arrow 提供了一个工厂函数 get() 来获取 Arrow 对象。所有的创建方式都集成在这一个工厂函数中:

Python
def get(
    source, # 输入源,会根据输入来决定如何解析
    locale: str = 'en-us', # 指定区域,主要牵扯打印输出
    tzinfo: str|tzinfo = 'UTC', # 时区,可以类似 "Asia/Shanghai" 这样的字符串
) -> Arrow:
    pass

该方法对于不同的输入源有不同的表现:

Python
import arrow

# 如果没有输入默认获取当前 UTC 时间
# 等价于 arrow.utcnow()
arrow.get()
<Arrow [2024-10-16T15:11:42.466164+00:00]>
# 也可以指定时区
arrow.get(tzinfo='Asia/Shanghai')
<Arrow [2024-10-16T23:18:13.861445+08:00]>

# 可以是另一个 Arrow 对象来获取一个副本
arw = arrow.utcnow()
arrow.get(arw)
<Arrow [2024-10-16T15:13:23.370452+00:00]>

# 可以是 datetime 对象来构造 Arrow
arrow.get(datetime(2013, 5, 5))
<Arrow [2013-05-05T00:00:00+00:00]>
# 注意 Arrow 是日期时间的结合体,如果只有日期它的时间都是 00
arrow.get(date(2013, 5, 5))
<Arrow [2013-05-05T00:00:00+00:00]>

# 如果是 float 或 int 会当作时间戳看待以获取 UTC 格式的时间戳
# 注意是基于 s 的时间戳
arrow.get(1367992474.293378)
<Arrow [2013-05-08T05:54:34.293378+00:00]>
arrow.get(1367992474)
<Arrow [2013-05-08T05:54:34+00:00]>

# 能够正确解析 ISO8601 规范的字符串
arrow.get('2013-09-29T01:26:43.830580')
<Arrow [2013-09-29T01:26:43.830580+00:00]>
arrow.get('20160413T133656.456289')
<Arrow [2016-04-13T13:36:56.456289+00:00]>

# 如果两个参数都是 str 会将第二个参数作为格式化字符串来解析第一个参数
arrow.get('2013-05-05 12:30:45 America/Chicago', 'YYYY-MM-DD HH:mm:ss ZZZ')
<Arrow [2013-05-05T12:30:45-05:00]>
# 可以连接多个解析字符串来处理多种情况
arrow.get('2013-05-05 12:30:45', ['MM/DD/YYYY', 'YYYY-MM-DD HH:mm:ss'])
<Arrow [2013-05-05T12:30:45+00:00]>

# 三个或更多参数就是直接构造
arrow.get(2013, 5, 5, 12, 30, 45)
<Arrow [2013-05-05T12:30:45+00:00]>

还有两个便捷的工厂函数:

  • arrow.now(): 当前的本地时间
  • arrow.utcnow(): 当前的 UTC 时间

Tips

注意 arrow.get() 默认返回的是 UTC 时间

Arrow 对象属性

arrow 所有的操作都绑定在 Arrow 对象上,通过工厂函数获取该对象后可以通过绑定在 Arrow 对象上的属性和方法来操作日期时间对象:

Python
class Arrow:
    # 基本属性
    year: int
    month: int
    day: int
    hour: int
    minute: int
    second: int
    microsecond: int
    tzinfo: tzinfo

    # 获取 date / datetime 内置对象
    date() -> datetime.date
    time() -> datetime.time
    datetime() -> datetime.datetime
    naive -> datetime.datetime

    # 替换和偏移
    replace(**kwargs) -> Arrow
    shift(**kwargs) -> Arrow

    # 格式化,类似于 strptime
    format(format_str) -> str

    # 范围和跨度
    span() -> tuple[Arrow]
    floor() -> Arrow
    ceil() -> Arrow

基本对象

直接通过 year、month 等属性来获取时间的指定对象。这其中比较特殊的就是时区:

Python
# 默认就是 UTC
Arrow.get().tzinfo
tzutc()

# 在一些需要 tzinfo 的地方我们可以通过下面的方式来获取
Arrow.now("Asia/Shanghai").tzinfo
tzfile('/usr/share/zoneinfo/Asia/Shanghai')

获取标准库 datetime 中的对象

为了和其他模块进行交互通常需要将 Arrow 转换为 Python 标准库提供的对象:

Python
a = arrow.utcnow()

# 时间对象
a.datetime
datetime.datetime(2013, 5, 7, 4, 38, 15, 447644, tzinfo=tzutc())

# 简单的时间对象
a.naive
datetime.datetime(2013, 5, 7, 4, 38, 15, 447644)

替换和偏移

他们都是通过属性来修改当前的 Arrow 对象返回一个新的 Arrow 对象:

Python
arw = arrow.utcnow()
<Arrow [2013-05-12T03:29:35.334214+00:00]>

arw.replace(hour=4, minute=40)
<Arrow [2013-05-12T04:40:35.334214+00:00]>

arw.shift(weeks=+3)
<Arrow [2013-06-02T03:29:35.334214+00:00]>

格式化

他和 strptime 有点类似,不过接受的格式化字符串不太一样:

属性 格式化 示例
year YYYY 2000, 2000 ...
year YY 00, 01 ...
month MMMM January, February ...
month MMM Jan, Feb, Mar ...
month MM 01, 02, ... 12
month M 1, 2 ... 12
day of year DDDD 001, 002 ... 365
day of year DDD 1, 2 ... 365
day of month DD 01, 02 ... 31
day of month D 1, 2 ... 31
day of week dddd Monday, Tuesday ...
day of week ddd Mon, Tue ...
day of week d 1, 2 ... 7
hour HH 00, 01 ... 24
hour H 0, 1 ... 24
hour hh 01, 02 ... 12
hour h 1, 2 ... 12
am/pm A AM, PM
am/pm a am, pm
minute mm 00, 01 ... 59
minute m 0, 1 ... 59
second ss 00, 01 ... 59
second s 0, 1 ... 59
Timezone ZZZ Asia/Shanghai, Europe/Warsaw ...
Timezone ZZ +08:00 -06:00 ...
Timezone Z +0800 -0600 ...
Second Timestamp X 1381685817
Ms Timestamp x 13816858179154
Python
arrow.utcnow().format('YYYY-MM-DD HH:mm:ss ZZ')
'2013-05-07 05:23:16 -00:00'

范围和跨度