每週一個 Python 模塊 | datetime

專欄地址:每週一個 Python 模塊html

datetime 包含用於處理日期和時間的函數和類。python

Time

時間值用time類表示。 time實例有屬性hourminutesecond,和microsecond,還能夠包括時區信息。git

import datetime

t = datetime.time(1, 2, 3)
print(t)	# 01:02:03
print('hour :', t.hour)	# hour : 1
print('minute :', t.minute)	# minute : 2
print('second :', t.second)	# second : 3
print('microsecond:', t.microsecond)	# microsecond: 0
print('tzinfo :', t.tzinfo)	# tzinfo : None
複製代碼

time實例只保留時間值,而不是與時間相關聯的日期。github

import datetime

print('Earliest :', datetime.time.min)	# Earliest : 00:00:00
print('Latest :', datetime.time.max)	# Latest : 23:59:59.999999
print('Resolution:', datetime.time.resolution)	# Resolution: 0:00:00.000001
複製代碼

minmax類屬性反映了時間在一天的有效範圍。函數

時間的分辨率限制在整個微秒。(也能夠說是一個微秒,詳見上面代碼 Resolution)spa

import datetime

for m in [1, 0, 0.1, 0.6]:
    try:
        print('{:02.1f} :'.format(m),
              datetime.time(0, 0, 0, microsecond=m))
    except TypeError as err:
        print('ERROR:', err)
  
# 輸出
# 1.0 : 00:00:00.000001
# 0.0 : 00:00:00
# ERROR: integer argument expected, got float
# ERROR: integer argument expected, got float 
複製代碼

微秒的浮點值會致使TypeError.net

Date

日期值用date 類表示。實例具備屬性yearmonthday。使用today()類方法能夠輕鬆建立當前日期。code

import datetime

today = datetime.date.today()
print(today)	# 2018-03-18
print('ctime :', today.ctime())	# ctime : Sun Mar 18 00:00:00 2018
tt = today.timetuple()
print('tuple : tm_year =', tt.tm_year)	# tuple : tm_year = 2018
print(' tm_mon =', tt.tm_mon)		# tm_mon = 3
print(' tm_mday =', tt.tm_mday)	# tm_mday = 18
print(' tm_hour =', tt.tm_hour)	# tm_hour = 0
print(' tm_min =', tt.tm_min)		# tm_min = 0
print(' tm_sec =', tt.tm_sec)		# tm_sec = 0
print(' tm_wday =', tt.tm_wday)	# tm_wday = 6
print(' tm_yday =', tt.tm_yday)	# tm_yday = 77
print(' tm_isdst =', tt.tm_isdst)	# tm_isdst = -1
print('ordinal:', today.toordinal())	# ordinal: 736771
print('Year :', today.year)	# Year : 2018
print('Mon :', today.month)	# Mon : 3
print('Day :', today.day)	# Day : 18
複製代碼

還有一些類方法,用於從 POSIX 時間戳或整數表示公曆中的日期值建立實例,其中 1 年 1 月 1 日爲 1,每一個後續日期將值遞增 1。orm

import datetime
import time

o = 733114
print(o)	# o : 733114
print(datetime.date.fromordinal(o))	# fromordinal(o) : 2008-03-13

t = time.time()
print(t)	# t : 1521404434.262209
print(datetime.date.fromtimestamp(t))	# fromtimestamp(t): 2018-03-18
複製代碼

此示例說明了fromordinal()fromtimestamp() 使用的不一樣值類型。htm

time同樣,可使用minmax屬性肯定支持的日期值範圍。

import datetime

print('Earliest :', datetime.date.min)	# Earliest : 0001-01-01
print('Latest :', datetime.date.max)	# Latest : 9999-12-31
print('Resolution:', datetime.date.resolution)	# Resolution: 1 day, 0:00:00
複製代碼

日期的精確度是成天。

建立新date實例的另外一種方法是使用replace()

import datetime

d1 = datetime.date(2008, 3, 29)
print('d1:', d1.ctime())	# d1: Sat Mar 29 00:00:00 2008

d2 = d1.replace(year=2009)
print('d2:', d2.ctime())	# d2: Sun Mar 29 00:00:00 2009
複製代碼

此示例更改年份,日期和月份保持不變。

timedeltas

可使用兩個datetime對象的作基本的計算,或經過將 datetimetimedelta 組合來計算將來和過去的日期。減去日期會產生一個timedelta,也能夠從日期中添加或減去timedelta以產生另外一個日期。timedelta的內部值以天,秒和微秒存儲。

import datetime

print('microseconds:', datetime.timedelta(microseconds=1))	# 0:00:00.000001
print('milliseconds:', datetime.timedelta(milliseconds=1))	# 0:00:00.001000
print('seconds :', datetime.timedelta(seconds=1))	# 0:00:01
print('minutes :', datetime.timedelta(minutes=1))	# 0:01:00
print('hours :', datetime.timedelta(hours=1))	# 1:00:00
print('days :', datetime.timedelta(days=1))	# 1 day, 0:00:00
print('weeks :', datetime.timedelta(weeks=1))	# 7 days, 0:00:00
複製代碼

傳遞給構造函數的中間級別值將轉換爲天,秒和微秒。

timedelta的完整持續時間可使用total_seconds()以秒數來檢索。

import datetime

for delta in [datetime.timedelta(microseconds=1),
              datetime.timedelta(milliseconds=1),
              datetime.timedelta(seconds=1),
              datetime.timedelta(minutes=1),
              datetime.timedelta(hours=1),
              datetime.timedelta(days=1),
              datetime.timedelta(weeks=1),
              ]:
    print('{:15} = {:8} seconds'.format(
        str(delta), delta.total_seconds())
    )

# 輸出 
# 0:00:00.000001 = 1e-06 seconds
# 0:00:00.001000 = 0.001 seconds
# 0:00:01 = 1.0 seconds
# 0:01:00 = 60.0 seconds
# 1:00:00 = 3600.0 seconds
# 1 day, 0:00:00 = 86400.0 seconds
# 7 days, 0:00:00 = 604800.0 seconds 
複製代碼

返回值是一個浮點數,以適應次秒持續時間。

日期計算

日期計算使用標準算術運算符。

import datetime

today = datetime.date.today()
print('Today :', today)	# Today : 2018-03-18

one_day = datetime.timedelta(days=1)
print('One day :', one_day)	# One day : 1 day, 0:00:00

yesterday = today - one_day
print('Yesterday:', yesterday)	# Yesterday: 2018-03-17

tomorrow = today + one_day
print('Tomorrow :', tomorrow)	# Tomorrow : 2018-03-19

print('tomorrow - yesterday:', tomorrow - yesterday)	# 2 days, 0:00:00
print('yesterday - tomorrow:', yesterday - tomorrow)	# -2 days, 0:00:00
複製代碼

示例說明了使用timedelta 對象計算新日期,能夠減去日期實例以生成 timedeltas(包括負 delta 值)。

timedelta對象還支持與整數,浮點數和其餘timedelta對象進行算術運算。

import datetime

one_day = datetime.timedelta(days=1)
print('1 day :', one_day)	# 1 day : 1 day, 0:00:00
print('5 days :', one_day * 5)	# 5 days : 5 days, 0:00:00
print('1.5 days :', one_day * 1.5)	# 1.5 days : 1 day, 12:00:00
print('1/4 day :', one_day / 4)	# 1/4 day : 6:00:00

# assume an hour for lunch
work_day = datetime.timedelta(hours=7)
meeting_length = datetime.timedelta(hours=1)
print('meetings per day :', work_day / meeting_length)	# meetings per day : 7.0
複製代碼

在此示例中,計算一天的幾個倍數,結果timedelta保持天數或小時數。最後一個示例演示瞭如何經過組合兩個timedelta對象來計算值。在這種狀況下,結果是浮點數。

日期和時間比較

可使用標準比較運算符比較日期和時間值,以肯定哪一個更早或更晚。

import datetime
import time

print('Times:')	# Times:
t1 = datetime.time(12, 55, 0)
print(' t1:', t1)	# t1: 12:55:00
t2 = datetime.time(13, 5, 0)
print(' t2:', t2)	# t2: 13:05:00
print(' t1 < t2:', t1 < t2)	# t1 < t2: True

print('Dates:')	# Dates:
d1 = datetime.date.today()
print(' d1:', d1)	# d1: 2018-03-18
d2 = datetime.date.today() + datetime.timedelta(days=1)
print(' d2:', d2)	# d2: 2018-03-19
print(' d1 > d2:', d1 > d2)	# d1 > d2: False
複製代碼

支持全部比較運算符。

組合日期和時間

使用datetime類來保存由日期和時間組件組成的值。與date同樣,有幾個簡單的類方法能夠建立datetime實例。

import datetime

print('Now :', datetime.datetime.now())
print('Today :', datetime.datetime.today())
print('UTC Now:', datetime.datetime.utcnow())
print()

FIELDS = [
    'year', 'month', 'day',
    'hour', 'minute', 'second',
    'microsecond',
]

d = datetime.datetime.now()
for attr in FIELDS:
    print('{:15}: {}'.format(attr, getattr(d, attr)))
    
# 輸出
# Now : 2018-03-18 16:20:34.811583
# Today : 2018-03-18 16:20:34.811616
# UTC Now: 2018-03-18 20:20:34.811627

# year : 2018
# month : 3
# day : 18
# hour : 16
# minute : 20
# second : 34
# microsecond : 811817
複製代碼

datetime實例具備datetime對象的全部屬性。

date同樣,datetime爲建立新實例提供了方便的類方法。它還包括 fromordinal()fromtimestamp()

import datetime

t = datetime.time(1, 2, 3)
print('t :', t)		# t : 01:02:03

d = datetime.date.today()
print('d :', d)		# d : 2018-03-18

dt = datetime.datetime.combine(d, t)
print('dt:', dt)	# dt: 2018-03-18 01:02:03
複製代碼

combine()從一個 date和一個time實例建立datetime實例。

格式化和解析

datetime 對象的默認字符串表示形式使用 ISO-8601 格式(YYYY-MM-DDTHH:MM:SS.mmmmmm)。可使用 strftime() 對其進行格式化。

import datetime

format = "%a %b %d %H:%M:%S %Y"

today = datetime.datetime.today()
print('ISO :', today)	# ISO : 2018-03-18 16:20:34.941204

s = today.strftime(format)
print('strftime:', s)	# strftime: Sun Mar 18 16:20:34 2018

d = datetime.datetime.strptime(s, format)
print('strptime:', d.strftime(format))	# strptime: Sun Mar 18 16:20:34 2018
複製代碼

使用datetime.strptime()于格式化字符串轉換爲 datetime實例。

Python的字符串格式化迷你語言可使用相同的格式代碼,方法是:在格式字符串的字段規範中放置它們。

import datetime

today = datetime.datetime.today()
print('ISO :', today)	# ISO : 2018-03-18 16:20:35.006116
print('{:%a %b %d %H:%M:%S %Y}'.format(today))	# Sun Mar 18 16:20:35 2018
複製代碼

每一個日期時間格式代碼仍必須之前綴爲前綴%,後續冒號將做爲文字字符處理,以包含在輸出中。

下表顯示了美國/東部時區 2016 年 1 月 13 日下午 5:00 的全部格式代碼。

符號 含義
%a 縮寫的工做日名稱 'Wed'
%A 完整的工做日名稱 'Wednesday'
%w 工做日編號 - 0(星期日)至6(星期六) '3'
%d 每個月的一天(零填充) '13'
%b 縮寫的月份名稱 'Jan'
%B 全月名稱 'January'
%m 一年中的一個月 '01'
%y 沒有世紀的一年 '16'
%Y 與世紀的一年 '2016'
%H 24小時制的小時 '17'
%I 12小時制的小時 '05'
%p 上午下午 'PM'
%M 分鐘 '00'
%S '00'
%f 微秒 '000000'
%z 時區感知對象的UTC偏移量 '-0500'
%Z 時區名稱 'EST'
%j 一年中的某一天 '013'
%W 一年中的一週 '02'
%c 當前區域設置的日期和時間表示形式 'Wed Jan 13 17:00:00 2016'
%x 當前區域設置的日期表示形式 '01/13/16'
%X 當前區域設置的時間表示 '17:00:00'
%% 文字%字符 '%'

時區

datetime中,時區由子類tzinfo表示。因爲tzinfo是一個抽象基類,應用程序須要定義一個子類併爲一些方法提供適當的實現以使其有用。

datetime確實在類timezone中使用了一個有點天真的實現,它使用 UTC 的固定偏移量,而且不支持一年中不一樣日期的不一樣偏移值,例如夏令時適用的地方,或者 UTC 的偏移量隨時間變化的狀況。

import datetime

min6 = datetime.timezone(datetime.timedelta(hours=-6))
plus6 = datetime.timezone(datetime.timedelta(hours=6))
d = datetime.datetime.now(min6)

print(min6, ':', d)	
print(datetime.timezone.utc, ':',
      d.astimezone(datetime.timezone.utc))
print(plus6, ':', d.astimezone(plus6))

# convert to the current system timezone
d_system = d.astimezone()
print(d_system.tzinfo, ' :', d_system)

# UTC-06:00 : 2018-03-18 14:20:35.123594-06:00
# UTC : 2018-03-18 20:20:35.123594+00:00
# UTC+06:00 : 2018-03-19 02:20:35.123594+06:00
# EDT : 2018-03-18 16:20:35.123594-04:00
複製代碼

要將日期時間值從一個時區轉換爲另外一個時區,請使用 astimezone()。在上面的示例中,顯示了 UTC 兩側 6 小時的兩個獨立時區,而且utc實例 from datetime.timezone也用於參考。最終輸出行顯示系統時區中的值,經過不帶參數的astimezone()調用獲取 。

經常使用操做總結

最後,總結一些經常使用的函數,能夠直接選取本身須要的進行使用,具體代碼見 Github 時間模塊經常使用操做


相關文檔:

pymotw.com/3/datetime/…

zhuanlan.zhihu.com/p/28209870

flowsnow.net/2017/09/07/…

相關文章
相關標籤/搜索