請啟用 JavaScript 來查看內容

Python 使用 Arrow 套件來處理日期時間

前言

在寫網路爬蟲時,應該都會遇到需要解析日期時間的處理,但是Python內建有關日期時間的套件用久了覺得有點卡手,像是有以下缺點:

  • 太多套件(time、datetime、calendar、dateutil、pytz等)。
  • 有時需要在不同格式之間轉換,不是這麼的方便或繁瑣,例如時間格式、字串、時間戳、localtime和utctime、時區。
  • 在某些方面較不直觀或難記,像是格式化字串的參數。

在某天碰巧在網路的論壇中發現有人推薦 Arrow,看了一下,好像蠻不錯用的。

例如我們想把某日期時間字串加上5小時,再轉回字串的話,使用內建的datetimeArrow來比較:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
# 使用內建的datetime
from datetime import datetime, timedelta

t = datetime.strptime("2020-07-25 10:00", "%Y-%m-%d %H:%M")
t = t + timedelta(hours=5)
t.strftime("%Y-%m-%d %H:%M")
# 2020-07-25 15:00


# 使用Arrow
import arrow

t = arrow.get("2020-07-25 10:00")
t = t.shift(hours=5)
t.format('YYYY-MM-DD HH:mm')
# 2020-07-25 15:00

安裝

1
pip install arrow

以下以撰寫文章時最新的版本 v0.15.7 為範例。
Arrow 官方GitHub
Arrow 官方文件

功能範例

創建時間

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
# 當前時間
t = arrow.now()
# 2020-07-25T22:12:08.803133+08:00

# 當前UTC時間
t = arrow.utcnow()
# 2020-07-25T14:12:08.803133+00:00

# 自訂時間
t = arrow.Arrow(2020, 7, 25, 21, 50, 45)
# 2020-07-25T21:50:45+00:00

# 取得其中的數值
t.year
# 2020
t.hour
# 21

t.timestamp    # 時間戳
# 1594504245

格式化成字串 [format]

格式化參數放置於文章最後。

1
2
3
4
5
t.format('YYYY/MM/DD HH:mm:ss')
# 2020/07/25 21:50:45

t.format('MMM DD dddd')
# Jul 25 Saturday

轉換為 datetime 函數中的 [datetime、date、time]

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
t = arrow.Arrow(2020, 7, 25, 21, 50, 45)
# <class 'arrow.arrow.Arrow'> 2020-07-25T21:50:45+00:00

t.datetime
# <class 'datetime.datetime'> 2020-07-25 21:50:45+00:00

t.date()
# <class 'datetime.date'> 2020-07-25

t.time()
# <class 'datetime.time'> 21:50:45

移動時間 [shift]

參數有 years, months, days, hours, minutes, seconds, microseconds, weeks, quarters, weekday。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
t = arrow.Arrow(2020, 7, 25, 21, 50, 45)

# 3天前
t.shift(days=-3)
# 2020-07-22T21:50:45+00:00

# 50天又2小時後
t.shift(days=50, hours=2)
# 2020-09-13T23:50:45+00:00

# 上星期
t.shift(weeks=-1)
# 2020-07-18T21:50:45+00:00

修改日期 [replace]

1
2
3
4
5
6
7
8
t = arrow.Arrow(2020, 7, 25, 21, 50, 45)

t.replace(year=2025, month=12, day=31)
# 2025-12-31T21:50:45+00:00

# 替換時區
t.replace(tzinfo='Asia/Taipei')
# 2020-07-25T21:50:45+08:00

轉換時區 [to]

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
t = arrow.Arrow(2020, 7, 25, 20, 00, 00)
# 2020-07-25T20:00:00+00:00

t.to('Asia/Taipei')
# 2020-07-26T04:00:00+08:00

t.to('local')
# 2020-07-26T04:00:00+08:00

t.to('utc')
# 2020-07-25T20:00:00+00:00

從不同的格式轉換為Arrow格式 [get]

他還可以自動判斷!

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
arrow.get('2020/10/09 16:15:14')
# 2020-10-09T16:15:14+00:00

arrow.get('2020-07-30T01:26:43.8')
# 2020-07-30T01:26:43.800000+00:00

arrow.get(datetime(2020, 7, 25, 10, 10, 30))
# 2020-07-25T10:10:30+00:00

arrow.get(date(2020, 7, 25))
# 2020-07-25T00:00:00+00:00

arrow.get(2020, 7, 25, 12, 30, 45)
# 2020-07-25T12:30:45+00:00

arrow.get("2020-07-25 11:30", "YYYY-MM-DD HH:mm")
# 2020-07-25T11:30:00+00:00

arrow.get(1595651445)
# 2020-07-25T04:30:45+00:00

arrow.get("1595651445", "X")
# 2020-07-25T04:30:45+00:00

產生一段範圍 [range span]

range:時間範圍內依某級別(hour)產生時間點
span:初始與結尾時間點

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
start = arrow.Arrow(2020, 7, 25, 11, 50)
end = arrow.Arrow(2020, 7, 25, 13, 50)
for t in arrow.Arrow.range('hour', start, end):
    print(t)
# 2020-07-25T11:50:00+00:00
# 2020-07-25T12:50:00+00:00
# 2020-07-25T13:50:00+00:00

arrow.now().span('hour')
# (<Arrow [2020-07-25T11:00:00+08:00]>, <Arrow [2020-07-25T11:59:59.999999+08:00]>)
arrow.now().span('hour', count=2)
# (<Arrow [2020-07-25T11:00:00+08:00]>, <Arrow [2020-07-25T12:59:59.999999+08:00]>)

人性化(敘述)方式呈現 [humanize]

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
arw = arrow.now().shift(hours=1)
arw.humanize()
# in an hour
arw = arrow.now().shift(hours=-2)
arw.humanize()
# 2 hours ago

# 也可以用中文顯示哦!!
# https://github.com/crsmithdev/arrow/blob/master/arrow/locales.py
arw.humanize(locale="zh_tw")
# 2小時前

# 指定要顯示的級別
arw = arrow.utcnow().shift(seconds=+8400)
arw.humanize(granularity="minute", locale="zh_tw")
# 140分鐘後
arw.humanize(granularity=["hour", "minute"], locale="zh_tw")
# 2小時 和 20分鐘後

# 也可以拿兩個時間來比對
a = arrow.now()
b = arrow.now().shift(weeks=1)
a.humanize(b, locale="zh_tw")
# 1週前

解析和格式化 參數

說明語法結果
Year 年YYYY2000, 2001, 2002 … 2012, 2013
YY00, 01, 02 … 12, 13
Month 月MMMMJanuary, February, March …
MMMJan, Feb, Mar …
MM01, 02, 03 … 11, 12
M1, 2, 3 … 11, 12
Day of Year 一年中的天數DDDD001, 002, 003 … 364, 365
DDD1, 2, 3 … 364, 365
Day of Month 一個月中的天數DD01, 02, 03 … 30, 31
D1, 2, 3 … 30, 31
Do1st, 2nd, 3rd … 30th, 31st
Day of Week 一週中的天數ddddMonday, Tuesday, Wednesday …
dddMon, Tue, Wed …
d1, 2, 3 … 6, 7
Hour 小時HH00, 01, 02 … 23, 24
H0, 1, 2 … 23, 24
hh01, 02, 03 … 11, 12
h1, 2, 3 … 11, 12
AM / PMAAM, PM, am, pm
aam, pm
Minute 分鐘mm00, 01, 02 … 58, 59
m0, 1, 2 … 58, 59
Second 秒ss00, 01, 02 … 58, 59
s0, 1, 2 … 58, 59
Sub-secondS0, 02, 003, 000006, 123123123123…
Timezone 時區ZZZAsia/Taipei, Europe/Warsaw, GMT …
ZZ-08:00, -07:00 … +07:00, +08:00
Z-0800, -0700 … +0700, +0800
Seconds Timestamp 時間戳X1381685817, 1381685817.915482
ms or µs Timestamp 時間戳x1569980330813, 1569980330813221

結語

其他更進階的語法可以前往Arrow 官方文件查閱~

相比Python內建的日期時間套件,用起來應該清楚、好用吧。
只是缺點是使用前要先安裝。




如有遇到其他問題,或文章內容有誤,歡迎底下留言~😙


參考:
Arrow 官方GitHub
Arrow 官方文件

當你認為全世界都在跟你做對時,
請記得 飛機是逆風而飛的。


🔻 如果覺得喜歡,歡迎在下方獎勵我 5 個讚~
分享

Jia
作者
Jia
軟體工程師 - Software Engineer