Python一行代码获取上个月:Arrow库实战指南
本文介绍使用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使用一行代码获取上个月月份的方法,希望对大家有所帮助。如果大家有任何疑问,请留言,小编会及时回复。在此非常感谢大家对本站网站的支持!
免责声明:本文内容仅供参考,不代表本站观点。转载或引用请注明出处。









