Python一行代码获取上个月:Arrow库实战指南

江岸
江岸
发布时间:2026-10-13| 6人浏览过
原创

本文介绍使用Python的Arrow库简化时间日期处理。通过shift方法,仅需一行代码即可准确获取上个月月份,避免datetime模块的边界bug。涵盖安装、常用API如humanize、format、时区转换及对象构建,帮助开发者高效处理时间相关需求。

在Python中进行时间日期处理是开发中的常见需求,因此时间处理模块在各类编程语言中都不可或缺,Python自然也不例外。Python提供了丰富的时间处理模块,包括datetime、time、calendar、dateutil和pytz等。同时,涉及的数据类型也多种多样,如date、time、datetime、tzinfo和timedelta等。

假设有一个需求:获取当前月份的前一个月。例如,如果当前是2018年1月,那么上个月就是2017年12月。实现这一目标通常需要经历多个步骤。

>>> import datetime
 # 1. 获取「今天」
 >>> today = datetime.date.today()
 # 2. 获取当前月的第一天
 >>> first = today.replace(day=1)
 # 3. 减一天,得到上个月的最后一天
 >>> last_month = first - datetime.timedelta(days=1)
 # 4. 格式化成指定形式
 >>> print(last_month.strftime("%Y%m"))
 201807
 >>>

这个过程显得相当繁琐,甚至让人怀疑这是否还是Python的代码风格。有人可能会建议使用datetime.replace方法将month减1,但这存在明显的缺陷,因为month参数的有效范围仅限于1到12。

>>> d.replace(month=d.month-1)
datetime.datetime(2018, 7, 24, 11, 29, 28, 929830)
month-11 就报错了
>>> d.replace(month=d.month-11)
ValueError: month must be in 1..12

你是否熟悉日期时间、时间戳和字符串之间的相互转换API?每次处理时间相关操作时,是否都需要查阅官方文档才能开始编码?查看time模块和datetime模块中各种类型之间的转换箭头图,可能会让人感到复杂和困惑。

无论如何,熟练掌握这些模块和API操作是必要的。即使记不住所有细节,至少也要通过手动编写几次来加深印象,以便下次遇到问题时能快速查阅文档,定位到具体的类和方法及其用法。

今天,我要强烈推荐一个时间日期处理库:Arrow。它的灵感来源于requests库,旨在将所有复杂的细节隐藏在后台,只保留对开发者友好的接口。这充分体现了“Keep It Simple and Stupid”的设计理念。

本文将带你初步了解并掌握Arrow库的使用方法。

安装

$ pip install arrow

使用

>>> a = arrow.now() # 当前本地时间
>>> a
<Arrow [2018-08-24T07:09:03.468562+08:00]>
>>> arrow.utcnow() # 当前utc时间
<Arrow [2018-08-23T23:11:50.147585+00:00]>

你可以将Arrow对象视为一个增强版的datetime对象。

通过Arrow对象,你可以轻松获取对应的datetime对象。

>>> t = a.datetime
>>> type(t)
<class 'datetime.datetime'>
>>> t
datetime.datetime(2018, 8, 24, 7, 17, 14, 884750, tzinfo=tzlocal())

通过Arrow对象,你还可以直接获取时间戳。

>>> a.timestamp
1535066234

你可以获取Arrow对象的年、月、日、时、分、秒等具体数值。

>>> a.year
2018
>>> a.month
8
>>> a.day
24
>>> a.hour
7

你可以获取Arrow对象的时间和日期部分。

>>> a.date()
datetime.date(2018, 8, 24)
>>> a.time()
datetime.time(7, 9, 3, 468562)

需要注意的是,获取时间和日期是通过方法调用实现的,而获取datetime和timestamp则是通过属性访问。

接下来,我们将介绍一些Arrow库中有趣且实用的方法。

shift

shift方法类似于游标卡尺,支持在时间轴上进行加减移位操作,可以针对年、月、日、时、分、秒以及星期进行调整。回到文章开头的需求,获取当前月份的前一个月,你可以这样编写代码:

>>> a.shift(months=-1)
<Arrow [2018-07-24T07:09:03.468562+08:00]>
>>> a.shift(months=-1).format("YYYYMM")
'201807'
>>>

只需指定参数months = -1即可。若要获取后一个月,设置month=+1(加号可省略)。这样,你可以基于任意Arrow时间对象进行向前或向后的时间调整。注意,month后面带有s,year同理。以下是一些示例。

增加一个月

>>> a.shift(months=1)
<Arrow [2018-09-24T07:09:03.468562+08:00]>

减少一个月

>>> a.shift(months=-1)
<Arrow [2018-07-24T07:09:03.468562+08:00]>

减少两年

>>> a.shift(years=-2)
<Arrow [2016-08-24T07:09:03.468562+08:00]>
>>>

增加一个小时

>>> a.shift(hours=1)
<Arrow [2018-08-24T08:09:03.468562+08:00]>

还可以按周进行加减操作。

>>> a.shift(weeks=1)
<Arrow [2018-08-31T07:09:03.468562+08:00]>

如果你需要明确指定修改为某一年或某一个月,可以使用replace方法。replace方法在datetime对象中也存在,两者的使用方式一致。

humanize

humanize方法将当前时刻转换为“多久以前”的可读字符串形式,默认输出为英文格式。通过指定locale参数,可以显示相应语言的格式。

>>> a.humanize()
'6 hours ago'
>>> a.humanize(locale='zh')
'6小时前'

format

format是一个格式化工具,可以根据指定的格式将Arrow对象转换为字符串。具体的格式Token请参考下图。

>>> a.format()
'2018-08-24 07:09:03+08:00'
>>> a.format("YYYY-MM-DD HH:mm:ss")
'2018-08-24 07:09:03'

to

to方法可以将本地时区转换为其他任意时区。例如:

>>> arrow.now()
<Arrow [2018-08-24T16:58:50.990657+08:00]>
>>> arrow.now().to("utc")
<Arrow [2018-08-24T08:59:04.316289+00:00]>
>>> arrow.now().to("utc").to("local")
<Arrow [2018-08-24T16:59:15.800847+08:00]>
>>> arrow.now().to("America/New_York")
<Arrow [2018-08-24T04:59:34.037182-04:00]>

构建Arrow对象

前面介绍了Arrow可以转换为datetime、str、date、time和timestamp,那么如何构建Arrow对象呢?除了使用now()和utcnow()方法外,你还可以使用get工厂方法,或者直接通过Arrow构造函数指定年、月、日、时、分、秒。

>>> arrow.Arrow(2018, 8, 24, 12, 30, 45)
<Arrow [2018-08-24T12:30:45+00:00]>
>>> arrow.Arrow(2018, 8, 24, 12, 30, 45, tzinfo='utc')
<Arrow [2018-08-24T12:30:45+00:00]>
>>> arrow.Arrow(2018, 8, 24, 12, 30, 45, tzinfo='local')
<Arrow [2018-08-24T12:30:45+08:00]>

get

第二种创建Arrow对象的方法是使用get方法。get方法“非常灵活”,直接看示例,跟着代码敲一遍即可理解。

# 不带参数,等价与 utcnow()
>>> arrow.get()
<Arrow [2018-08-24T07:11:50.528742+00:00]>
# 接受时间戳参数
>>> arrow.get(1535113845)
# 接受一个datetime对象
>>> arrow.get(datetime(2018,8,24))
<Arrow [2018-08-24T00:00:00+00:00]>
# 接收一个date对象
>>> from datetime import date
>>> arrow.get(date(2018,7,24))
<Arrow [2018-07-24T00:00:00+00:00]>
# 接收日期格式的字符串
>>> arrow.get("2018-08-11 12:30:56")
<Arrow [2018-08-11T12:30:56+00:00]>
# 接收日期字符串,并指定格式
>>> arrow.get("18-08-11 12:30:56", "YY-MM-DD HH:mm:ss")
<Arrow [2018-08-11T12:30:56+00:00]>

Arrow的不足

关于get方法,虽然看似强大且使用灵活,能接受各种参数,但也带来了一些问题,甚至可能引发bug。例如:

>>> arrow.get("2018-7-11")
<Arrow [2018-01-01T00:00:00+00:00]>

期望的结果应该是2018-07-11,但程序并未提示错误。正确的做法是指定格式,因为你传入的字符串并非标准日期格式。

>>> arrow.get("2018-7-11", "YYYY-M-DD")
<Arrow [2018-07-11T00:00:00+00:00]>

试图通过一个方法兼容多种情况是极其困难的,这会导致内部实现变得非常复杂,用户使用起来也会感到混乱。

总结

以上介绍了Python使用一行代码获取上个月月份的方法,希望对大家有所帮助。如果大家有任何疑问,请留言,小编会及时回复。在此非常感谢大家对本站网站的支持!

相关标签:

免责声明:本文内容仅供参考,不代表本站观点。转载或引用请注明出处。

Python 相关产品和应用

全部下载
Selenium

Selenium

4.51.0 · Windows

用于浏览器自动化和 Web 测试的 Python 工具。

scikit-learn

scikit-learn

1.9.1 · Windows

常用 Python 机器学习算法与模型评估工具库。

Black

Black

26.10.1 · Windows

强调一致性的 Python 自动代码格式化工具。

Ruff

Ruff

0.17.1 · macOS

由 Rust 编写的高速 Python 代码检查和格式化工具。

pytest

pytest

9.1.1 · Windows

简洁而强大的 Python 自动化测试框架。

FastAPI

FastAPI

0.146.0 · Windows

高性能 Python API 框架,支持类型提示和自动接口文档。

Flask

Flask

3.1.3 · Windows

轻量灵活的 Python Web 应用框架。

Django

Django

6.1.2 · Windows

成熟的 Python Web 框架,适合构建内容站点和业务系统。

Spyder

Spyder

6.1.7 · Windows

面向科学计算与数据分析的 Python 集成开发环境。

SciPy

SciPy

1.18.1 · Windows

面向科学、工程和技术计算的 Python 算法库。