超越datetime:Arrow,Python中的日期时间管理大师

datetime,arrow,python · 浏览次数 : 4

小编点评

Arrow是一个用于创建、操作、格式化和转换日期、时间和时间戳的Python库。它提供了简洁、人性化的API,使得处理日期和时间变得更加容易。与Python标准库相比,Arrow具有以下优势: 1. 更易用性:Arrow的API设计得更加直观和易于理解,降低了使用Python内置模块的复杂性。 2. 功能丰富:Arrow支持多种日期、时间和时间戳的操作,如创建、解析、格式化和转换等。 3. 时区感知:Arrow能够自动处理时区转换,支持多种时区,方便在不同地区使用。 4. 自动规范化:Arrow会自动规范化日期和时间,减少了手动处理的冗余操作。 5. 支持多种语言:Arrow支持多种语言,可以根据不同的需求进行本地化。 总之,Arrow是一个功能强大、易于使用的日期和时间处理库,可以大大简化Python中日期和时间的操作。

正文

介绍

Arrow是一个Python库,它提供了一种合理且对人类友好的方法来创建、操作、格式化和转换日期、时间和时间戳。它实现了对datetime类型的更新,填补了功能上的空白,提供了一个智能的模块API,支持许多常见的创建场景。简单来说,它可以帮助您使用更少的导入和更少的代码来处理日期和时间。

Arrow以时间之箭命名,并且受到moment.jsrequests的极大启发。

为什么要使用Arrow而不是内置模块?

Python的标准库和其他一些低级模块拥有近乎完整的日期、时间和时区功能,但从可用性的角度来看,它们的工作效果并不理想:

  • 模块太多:datetimetimecalendardateutilpytz

  • 类型太多:datetimedatetimetzinfotimedeltarelativedelta

  • 时区和时间戳转换冗长且不愉快

  • 通常情况下都是时区不敏感的

  • 功能上存在gap:ISO 8601支持、时区间隔支持、不够人性化

特性

  • 完全实现的,可替代datetime

  • 支持Python 3.6+

  • 默认支持时区感知和UTC

  • 为许多常见输入场景提供超简单的创建选项

  • shift方法支持相对偏移,包括周

  • 自动格式化和解析字符串

  • 广泛支持ISO 8601标准

  • 时区转换

  • 支持dateutilpytzZoneInfo tzinfo对象

  • 生成时间段、范围、下限和上限,适用于从微秒到年的时间框架

  • 使用不断增长的贡献语言环境人性化日期和时间

  • 可扩展为您自己的Arrow派生类型

  • 全面支持PEP 484风格的类型提示

快速开始

安装

使用 pip or pipenv:

pip install -U arrow

简单使用

>>> import arrow
>>> arrow.get('2024-06-13T17:23:58.970460+08:00')
<Arrow [2024-06-13T17:23:58.970460+08:00]>

>>> utc = arrow.utcnow()
>>> utc
<Arrow [2024-06-13T08:37:39.950050+00:00]>

>>> utc = utc.shift(hours=-1)
>>> utc
<Arrow [2024-06-13T07:37:39.950050+00:00]>

>>> local = utc.to('Asia/Shanghai')
>>> local
<Arrow [2024-06-13T15:37:39.950050+08:00]>

>>> local.timestamp()
1718264259.95005

>>> local.format()
'2024-06-13 15:37:39+08:00'

>>> local.format('YYYY-MM-DD HH:mm:ss ZZ')
'2024-06-13 15:37:39 +08:00'

>>> local.humanize()
'an hour ago'

>>> local.humanize(locale='zh-cn')
'1小时前'

用户指南

Creation(创建对象)

通过now方法创建:

>>> arrow.utcnow()
<Arrow [2024-06-13T09:03:42.591212+00:00]>
>>> arrow.now()
<Arrow [2024-06-13T17:04:00.926319+08:00]>
>>> arrow.now('Asia/Shanghai')
<Arrow [2024-06-13T17:04:25.058905+08:00]>

通过时间戳创建 (int or float):

>>> arrow.get(1718264259) 
<Arrow [2024-06-13T07:37:39+00:00]>
>>> arrow.get(1718264259.95005)
<Arrow [2024-06-13T07:37:39.950050+00:00]>

使用无时区时间、有时区时间,或者灵活指定时区:

>>> arrow.get(datetime.utcnow())
<Arrow [2024-06-13T09:14:15.099808+00:00]>
>>> arrow.get(datetime(2024, 6, 13), 'Asia/Shanghai') 
<Arrow [2024-06-13T00:00:00+08:00]>
>>> from dateutil import tz
>>> arrow.get(datetime(2024, 6, 13), tz.gettz('Asia/Shanghai')) 
<Arrow [2024-06-13T00:00:00+08:00]>
>>> arrow.get(datetime.now(),tz.gettz('Asia/Shanghai')) 
<Arrow [2024-06-13T17:16:02.309002+08:00]>

从字符串转换:

>>> arrow.get('2024-06-13 15:30:45', 'YYYY-MM-DD HH:mm:ss') 
<Arrow [2024-06-13T15:30:45+00:00]>

从文本中查找日期:

>>> arrow.get('June was born in May 1980', 'MMMM YYYY')
<Arrow [1980-05-01T00:00:00+00:00]>

自动识别ISO 8601格式的字符串,并解析出相应的日期时间对象,包括时区信息:

>>> arrow.get('2024-06-13T15:34:00.000-08:00') 
<Arrow [2024-06-13T15:34:00-08:00]>

直接实例化Arrow对象(使用datetime类一样的参数):

>>> arrow.get(2024, 6, 13)
<Arrow [2024-06-13T00:00:00+00:00]>
>>>
>>> arrow.Arrow(2024, 6, 13)
<Arrow [2024-06-13T00:00:00+00:00]>

Properties(属性)

获取日期时间或时间戳表示形式:

>>> a = arrow.utcnow()
>>> a.datetime  
datetime.datetime(2024, 6, 13, 9, 25, 1, 195217, tzinfo=tzutc())

获取一个原生的时间,包含tzinfo:

>>> a.naive
datetime.datetime(2024, 6, 13, 9, 25, 1, 195217)
>>> a.tzinfo
tzutc()

获取任意日期时间值:

>>> a.year
2024
>>> a.month
6

调用datetime类相关函数和属性:

>>> a.date()
datetime.date(2024, 6, 13)
>>> a.time()
datetime.time(9, 25, 1, 195217)

Replace & Shift(替换和偏移)

获取一个新的Arrow对象,更改其属性,就像处理datetime类型一样:

>>> arw = arrow.utcnow()
>>> arw
<Arrow [2024-06-13T09:33:30.538303+00:00]>
>>> arw.replace(hour=4, minute=40)
<Arrow [2024-06-13T04:40:30.538303+00:00]>

或者,将属性向前或向后移动的:

>>> arw.shift(weeks=+3)
<Arrow [2024-07-04T09:33:30.538303+00:00]>
>>> arw.shift(days=-3)  
<Arrow [2024-06-10T09:33:30.538303+00:00]>

甚至,直接替换时区

>>> arw.replace(tzinfo='US/Pacific')
<Arrow [2024-06-13T09:33:30.538303-07:00]>

Format(格式化)

arrow.utcnow().format('YYYY-MM-DD HH:mm:ss ZZ')
'2024-06-13 09:34:54 +00:00'

Convert(转换)

按名称或tzinfo从UTC转换为其他时区:

>>> utc = arrow.utcnow()
>>> utc
<Arrow [2024-06-13T09:36:22.204239+00:00]>

>>> utc.to('US/Pacific')
<Arrow [2024-06-13T02:36:22.204239-07:00]>

>>> utc.to(tz.gettz('US/Pacific'))
<Arrow [2024-06-13T02:36:22.204239-07:00]>

或者使用简写:

>>> utc.to('local')
<Arrow [2024-06-13T17:36:22.204239+08:00]>

>>> utc.to('local').to('utc')
<Arrow [2024-06-13T09:36:22.204239+00:00]>

Humanize(人性化)

相对于现在时间的人性化表现:

>>> past = arrow.utcnow().shift(hours=-1)
>>> past.humanize()
'an hour ago'

或者另一个Arrow对下或日期时间:

>>> present = arrow.utcnow()
>>> future = present.shift(hours=2)
>>> future.humanize(present)
'in 2 hours'

将时间表示为相对时间或仅包括时间距离:

>>> present = arrow.utcnow()
>>> future = present.shift(hours=2)
>>> future.humanize(present)
'in 2 hours'
>>> future.humanize(present, only_distance=True)
'2 hours'

指定特定的时间粒度(或多个):

>>> present = arrow.utcnow()
>>> future = present.shift(minutes=66)
>>> future.humanize(present, granularity="minute")
'in 66 minutes'
>>> future.humanize(present, granularity=["hour", "minute"])
'in an hour and 6 minutes'
>>> present.humanize(future, granularity=["hour", "minute"])
'an hour and 6 minutes ago'
>>> future.humanize(present, only_distance=True, granularity=["hour", "minute"])
'an hour and 6 minutes'

支持不同时区的语言显示:

>>> future = arrow.utcnow().shift(hours=1)

>>> future.humanize(a, locale='ru')
'через час'

>>> future.humanize(a, locale='zh-cn') 
'1小时后'

Dehumanize(去人性化)

使用人类可读的字符串描述,并使用它转换到过去的时间:

>>> arw = arrow.utcnow()
>>> arw
<Arrow [2024-06-13T09:47:35.616633+00:00]>

>>> earlier = arw.dehumanize("2 days ago")
>>> earlier
<Arrow [2024-06-11T09:47:35.616633+00:00]>

或者用它来转换到未来的时间:

>>> arw = arrow.utcnow()
>>> arw
<Arrow [2024-06-13T09:47:35.616633+00:00]>


>>> later = arw.dehumanize("in a month")
>>> later
<Arrow [2024-07-13T09:47:35.616633+00:00]>

支持不同时区的语言转换:

>>> later = arw.dehumanize('1小时后', locale="zh-cn") 
>>> later
<Arrow [2024-06-13T10:47:35.616633+00:00]>

Ranges & Spans(范围&跨度)

获取任意单位的时间跨度:

>>> arrow.utcnow().span('hour')
(<Arrow [2024-06-13T09:00:00+00:00]>, <Arrow [2024-06-13T09:59:59.999999+00:00]>)
>>> arrow.utcnow().span('day')  
(<Arrow [2024-06-13T00:00:00+00:00]>, <Arrow [2024-06-13T23:59:59.999999+00:00]>)

或者只获取最大最小值:

>>> arrow.utcnow().floor('hour')
<Arrow [2024-06-13T09:00:00+00:00]>
>>> arrow.utcnow().ceil('hour')
<Arrow [2024-06-13T09:59:59.999999+00:00]>

您还可以获取一系列时间跨度:

>>> start = datetime(2024, 6, 13, 12, 30) 
>>> end = datetime(2024, 6, 13, 17, 15)
 
>>> for r in arrow.Arrow.span_range('hour', start, end):
...     print(r)
...
(<Arrow [2024-06-13T12:00:00+00:00]>, <Arrow [2024-06-13T12:59:59.999999+00:00]>)
(<Arrow [2024-06-13T13:00:00+00:00]>, <Arrow [2024-06-13T13:59:59.999999+00:00]>)
(<Arrow [2024-06-13T14:00:00+00:00]>, <Arrow [2024-06-13T14:59:59.999999+00:00]>)
(<Arrow [2024-06-13T15:00:00+00:00]>, <Arrow [2024-06-13T15:59:59.999999+00:00]>)
(<Arrow [2024-06-13T16:00:00+00:00]>, <Arrow [2024-06-13T16:59:59.999999+00:00]>)
(<Arrow [2024-06-13T17:00:00+00:00]>, <Arrow [2024-06-13T17:59:59.999999+00:00]>)

或者只是获取一系列时间点:

>>> start = datetime(2024, 6, 13, 12, 30) 
>>> end = datetime(2024, 6, 13, 17, 15)

>>> for r in arrow.Arrow.range('hour', start, end):
...     print(repr(r))
...
<Arrow [2024-06-13T12:30:00+00:00]>
<Arrow [2024-06-13T13:30:00+00:00]>
<Arrow [2024-06-13T14:30:00+00:00]>
<Arrow [2024-06-13T15:30:00+00:00]>
<Arrow [2024-06-13T16:30:00+00:00]>

Factories(工厂方法)

使用工厂模式实现自定义Arrow派生类型,来继承和扩展Arrow的模块API。首先,定义您的类型:

class CustomArrow(arrow.Arrow):
...
...     def days_till_xmas(self):
...         xmas = arrow.Arrow(self.year, 12, 25)
...         if self > xmas:
...             xmas = xmas.shift(years=1)
...         return (xmas - self).days

然后使用工厂:

>>> factory = arrow.ArrowFactory(CustomArrow)
>>> custom = factory.utcnow()
>>> custom
<CustomArrow [2024-06-13T10:02:04.898347+00:00]>
>>> custom.days_till_xmas()
194

Supported Tokens(支持的格式)

使用以下标记进行分析和格式化。请注意,它们与strptime的标记不同:

  标记格式 示例
Year YYYY 2000, 2001, 2002 … 2012, 2013
  YY 00, 01, 02 … 12, 13
Month MMMM January, February, March …1
  MMM Jan, Feb, Mar …1
  MM 01, 02, 03 … 11, 12
  M 1, 2, 3 … 11, 12
Day of Year DDDD 001, 002, 003 … 364, 365
  DDD 1, 2, 3 … 364, 365
Day of Month DD 01, 02, 03 … 30, 31
  D 1, 2, 3 … 30, 31
  Do 1st, 2nd, 3rd … 30th, 31st
Day of Week dddd Monday, Tuesday, Wednesday …2
  ddd Mon, Tue, Wed …2
  d 1, 2, 3 … 6, 7
ISO week date W 2011-W05-4, 2019-W17
Hour HH 00, 01, 02 … 23, 24
  H 0, 1, 2 … 23, 24
  hh 01, 02, 03 … 11, 12
  h 1, 2, 3 … 11, 12
AM / PM A AM, PM, am, pm1
  a am, pm1
Minute mm 00, 01, 02 … 58, 59
  m 0, 1, 2 … 58, 59
Second ss 00, 01, 02 … 58, 59
  s 0, 1, 2 … 58, 59
Sub-second S 0, 02, 003, 000006, 123123123123…3
Timezone ZZZ Asia/Baku, Europe/Warsaw, GMT …4
  ZZ -07:00, -06:00 … +06:00, +07:00, +08, Z
  Z -0700, -0600 … +0600, +0700, +08, Z
Seconds Timestamp X 1381685817, 1381685817.915482 …5
ms or µs Timestamp x 1569980330813, 1569980330813221

Built-in Formats(内置格式)

>>> arw = arrow.utcnow()
>>> arw.format(arrow.FORMAT_ATOM)
'2024-06-13 10:05:40+00:00'
>>> arw.format(arrow.FORMAT_COOKIE)
'Thursday, 13-Jun-2024 10:05:40 UTC'
>>> arw.format(arrow.FORMAT_RSS)
'Thu, 13 Jun 2024 10:05:40 +0000'
>>> arw.format(arrow.FORMAT_RFC822)
'Thu, 13 Jun 24 10:05:40 +0000'
>>> arw.format(arrow.FORMAT_RFC850)
'Thursday, 13-Jun-24 10:05:40 UTC'
>>> arw.format(arrow.FORMAT_RFC1036)
'Thu, 13 Jun 24 10:05:40 +0000'
>>> arw.format(arrow.FORMAT_RFC1123)
'Thu, 13 Jun 2024 10:05:40 +0000'
>>> arw.format(arrow.FORMAT_RFC2822)
'Thu, 13 Jun 2024 10:05:40 +0000'
>>> arw.format(arrow.FORMAT_RFC3339)  
'2024-06-13 10:05:40+00:00'
>>> arw.format(arrow.FORMAT_W3C)
'2024-06-13 10:05:40+00:00'

Escaping Formats(转义格式)

解析和格式化时,可以通过将格式字符串中的标记、短语和正则表达式括在方括号中来转义它们。

标记格式

>>> fmt = "YYYY-MM-DD h [h] m"

>>> arw = arrow.get("2024-06-13 8 h 40", fmt) 
>>> arw.format(fmt)                           
'2024-06-13 8 h 40'

>>> fmt = "YYYY-MM-DD h [hello] m"
>>> arw = arrow.get("2024-06-13 8 hello 40", fmt) 
>>> arw
<Arrow [2024-06-13T08:40:00+00:00]>
>>> arw.format(fmt)
'2024-06-13 8 hello 40'

>>> fmt = "YYYY-MM-DD h [hello world] m"
>>> arw = arrow.get("2024-05-16 8 hello world 40", fmt) 
>>> arw.format(fmt)
'2024-05-16 8 hello world 40'

正则

您还可以通过将正则表达式括在方括号内来转义它们。在下面的示例中,我们使用正则表达式s+来匹配分隔标记的任意数量的空白字符。如果您不提前知道令牌之间的空间数(例如,在日志文件中),这将非常有用。

>>> fmt = r"ddd[\s+]MMM[\s+]DD[\s+]HH:mm:ss[\s+]YYYY"
>>> arrow.get("Thu Jun 16 16:41:45 2024", fmt)
<Arrow [2024-06-16T16:41:45+00:00]>

>>> arrow.get("Thu \tJun 16     16:41:45        2024", fmt) 
<Arrow [2024-06-16T16:41:45+00:00]>

>>> arrow.get("Thu Jun 16    16:41:45  2024", fmt) 
<Arrow [2024-06-16T16:41:45+00:00]>

Punctuation(标点符号)

日期和时间格式的两侧可以用以下列表中的一个标点符号隔开:、.;:!" \ ' [ ] { } ( ) < >`

>>> arrow.get("Cool date: 2024-06-16T09:12:45.123456+04:30.", "YYYY-MM-DDTHH:mm:ss.SZZ")
<Arrow [2024-06-16T09:12:45.123456+04:30]>

>>> arrow.get("Tomorrow (2024-06-16) is Halloween!", "YYYY-MM-DD") 
<Arrow [2024-06-16T00:00:00+00:00]>

>>> arrow.get("Halloween is on 2024.06.16.", "YYYY.MM.DD") 
<Arrow [2024-06-16T00:00:00+00:00]>

>>> arrow.get("It's Halloween tomorrow (2024-06-16)!", "YYYY-MM-DD") 
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "C:\Users\LocalCache\local-packages\Python312\site-packages\arrow\api.py", line 91, in get
    return _factory.get(*args, **kwargs)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "C:\Users\LocalCache\local-packages\Python312\site-packages\arrow\factory.py", line 292, in get
    dt = parser.DateTimeParser(locale).parse(
         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "C:\Users\LocalCache\local-packages\Python312\site-packages\arrow\parser.py", line 323, in parse
    raise ParserMatchError(
arrow.parser.ParserMatchError: Failed to match 'YYYY-MM-DD' when parsing "It's Halloween tomorrow (2024-06-16)!".

Redundant Whitespace(冗余空白字符处理)

多余的空白字符(空格、制表符和换行符)可以通过将normalize_whitespace标志传递到arrow.get来自动规范化:

>>> arrow.get('\t \n  2024-06-13T12:30:45.123456 \t \n', normalize_whitespace=True) 
<Arrow [2024-06-13T12:30:45.123456+00:00]>

>>> arrow.get('2024-06-13  T \n   12:30:45\t123456', 'YYYY-MM-DD T HH:mm:ss S', normalize_whitespace=True) 
<Arrow [2024-06-13T12:30:45.123456+00:00]>

 

与超越datetime:Arrow,Python中的日期时间管理大师相似的内容:

超越datetime:Arrow,Python中的日期时间管理大师

介绍 Arrow是一个Python库,它提供了一种合理且对人类友好的方法来创建、操作、格式化和转换日期、时间和时间戳。它实现了对datetime类型的更新,填补了功能上的空白,提供了一个智能的模块API,支持许多常见的创建场景。简单来说,它可以帮助您使用更少的导入和更少的代码来处理日期和时间。 Ar

[转帖]超越官方的民间测评:基于 SPEC CPU 2006 的国产龙芯 3A4000 处理器性能评测

https://baijiahao.baidu.com/s?id=1695009412896463654&wfr=spider&for=pc 关注 “跑分” 这件事,相信各位读者对此并不陌生。“不服跑个分” 已经成为了某些手机发布时的保留节目。对于普通用户来说,最常用的跑分程序大概就是鲁大师和安兔兔

超越内存限制:深入探索内存池的工作原理与实现

设计一个内存池,可以有效的避免内存碎片和避免频繁的内存创建释放。

FinOps首次超越安全成为企业头等大事丨云计算趋势报告

随着云计算在过去十年中的广泛应用,云计算用户所面临的一个持续不变的趋势是:安全一直是用户面临的首要挑战。然而,这种情况正在发生转变。 知名IT软件企业 Flexera 对云计算决策者进行年度调研已经持续12年,而今年安全问题首次没有成为最大挑战。在3月8日发布的《Flexera 2023年云计算现状

InstructPix2Pix: 动动嘴皮子,超越PS

摘要:InstructPix2Pix提出了一种使用文本编辑图像的方法:给定输入图像和编辑指令,告诉模型要做什么,模型将遵循这些指令来编辑图像。 本文分享自华为云社区《InstructPix2Pix: 动动嘴皮子,超越PS》,作者:杜甫盖房子。 InstructPix2Pix: Learning to

17岁中专女生勇夺2024阿里全球数学赛12名好成绩,今天,站在程序员的视角,我们来聊聊数学对编程的价值与意义...

大家好,我是程序员陶朱公,一个认真生活,总想超越自己的程序员。 前言 相信这两天,大家都刷屏到了一个比较热度的新闻——17岁中专女生在今年这届阿里举办的全球数赛中,勇夺第12名的好成绩。 ↓↓↓ 看到这里,可能有小伙伴会觉得有点疑惑:又不是第一名,不明白第12名的她,为什么会引起社会这么大的一个反响

【OpenVINO™】在 C# 中使用OpenVINO™ 部署PP-YOLOE实现物体检测

PP-YOLOE是基于PP-YOLOv2的优秀单级无锚模型,超越了各种流行的YOLO模型。PP-YOLOE有一系列型号,命名为s/m/l/x,通过宽度乘数和深度乘数进行配置。PP-YOLOE避免使用特殊的运算符,如可变形卷积或矩阵NMS,以便友好地部署在各种硬件上。 在本文中,我们将使用OpenVI...

TGI 基准测试

本文主要探讨 TGI 的小兄弟 - TGI 基准测试工具。它能帮助我们超越简单的吞吐量指标,对 TGI 进行更全面的性能剖析,以更好地了解如何根据实际需求对服务进行调优并按需作出最佳的权衡及决策。如果你曾觉得 LLM 服务部署成本太高,或者你想对部署进行调优,那么本文很适合你! 我将向大家展示如何轻

AlexNet论文解读

前言 作为深度学习的开山之作AlexNet,确实给后来的研究者们很大的启发,使用神经网络来做具体的任务,如分类任务、回归(预测)任务等,尽管AlexNet在今天看来已经有很多神经网络超越了它,但是它依然是重要的。AlexNet的作者Alex Krizhevsky首次在两块GTX 580 GPU上做神

8个云成本优化的最佳实践

在《2022年云计算现状报告》中,国际知名软件资产管理商 Flexera 通过对近千家企业进行调查得出数据:企业平均浪费32%的云业务支出。随后,在2023年的报告中,FinOps 12年来首次超越安全,成为诸多企业关注的头等大事。 本文我们将展开聊聊企业乃至开发人员如何进行云成本优化。 1、设置指