Python 有兩個時間相關的內建模組 : time 與 datetime, 其中 time 模組主要是以 UNIX 時間戳來處理低階的時間資訊, 但其解析度較低只到秒而已, 無法支援證交所交易資訊精確度高達微秒之要求, 這就是 datetime 模組派上用場的時候了 (datetime 的時間解析度為微秒). 此外, datetime 模組經常與 Pandas 套件搭配用來處理時間序列資料. 關於 time 模組用法參考 :
參考書籍 :
# Python 自動化的樂趣 (碁峰, H&C) 第 15 章
# 零基礎入門的 Python 自動化投資 (采實, 量化通) 第 4 章
# 一本精通 Python 範例應用大全 (深智, 張宗彥) 第 9-4 節
# Python 股票演算法交易-145 個關鍵技巧詳解 (博碩, 酆世昌 & 劉承彥) 技巧 14
首先用 dir() 檢視 datetime 模組的內容 :
>>> import datetime
>>> dir(datetime)
['MAXYEAR', 'MINYEAR', '__all__', '__builtins__', '__cached__', '__doc__', '__file__', '__loader__', '__name__', '__package__', '__spec__', 'date', 'datetime', 'datetime_CAPI', 'sys', 'time', 'timedelta', 'timezone', 'tzinfo']
datetime 的成員大多是類別, 可以用下列模組中的 list_members() 函式來檢視成員類型 :
# members.py
import inspect
def varname(x):
return [k for k,v in inspect.currentframe().f_back.f_locals.items() if v is x][0]
def list_members(parent_obj):
members=dir(parent_obj)
parent_obj_name=varname(parent_obj)
for mbr in members:
child_obj=eval(parent_obj_name + '.' + mbr)
if not mbr.startswith('_'):
print(mbr, type(child_obj))
參考 :
>>> from members import list_members
>>> list_members(datetime)
MAXYEAR <class 'int'>
MINYEAR <class 'int'>
date <class 'type'>
datetime <class 'type'>
datetime_CAPI <class 'PyCapsule'>
sys <class 'module'>
time <class 'type'>
timedelta <class 'type'>
timezone <class 'type'>
tzinfo <class 'type'>
常用的有五個類別 :
- date : 處理日期之類別
- time : 處理時間之類別
- datetime : 處理日期與時間之類別
- timedelta : 處理時間差之類別
- timezone : 處理時區之類別
在資料科學中以 datetime 與 timedelta 類別最常用.
一. 使用 datetime.date 類別處理日期 :
date 類別用來處理日期相關資訊, 先用 dir() 檢視類別成員 :
>>> from datetime import date
>>> dir(date)
['__add__', '__class__', '__delattr__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__gt__', '__hash__', '__init__', '__init_subclass__', '__le__', '__lt__', '__ne__', '__new__', '__radd__', '__reduce__', '__reduce_ex__', '__repr__', '__rsub__', '__setattr__', '__sizeof__', '__str__', '__sub__', '__subclasshook__', 'ctime', 'day', 'fromisocalendar', 'fromisoformat', 'fromordinal', 'fromtimestamp', 'isocalendar', 'isoformat', 'isoweekday', 'max', 'min', 'month', 'replace', 'resolution', 'strftime', 'timetuple', 'today', 'toordinal', 'weekday', 'year']
用上面的自訂模組 members 之 list_members() 檢視 :
>>> list_members(date)
ctime <class 'method_descriptor'>
day <class 'getset_descriptor'>
fromisocalendar <class 'builtin_function_or_method'>
fromisoformat <class 'builtin_function_or_method'>
fromordinal <class 'builtin_function_or_method'>
fromtimestamp <class 'builtin_function_or_method'>
isocalendar <class 'method_descriptor'>
isoformat <class 'method_descriptor'>
isoweekday <class 'method_descriptor'>
max <class 'datetime.date'>
min <class 'datetime.date'>
month <class 'getset_descriptor'>
replace <class 'method_descriptor'>
resolution <class 'datetime.timedelta'>
strftime <class 'method_descriptor'>
timetuple <class 'method_descriptor'>
today <class 'builtin_function_or_method'>
toordinal <class 'method_descriptor'>
weekday <class 'method_descriptor'>
year <class 'getset_descriptor'>
其中有一個很常用的內建函式 today(), 此乃靜態方法毋須建立物件可直接呼叫, 它會傳回今日日期的 date 物件 :
>>> d=date.today()
>>> type(d)
<class 'datetime.date'>
>>> d
datetime.date(2024, 8, 13)
>>> print(d)
2024-08-13
可以將 date 物件垂給 str() 轉成 'YYYY-mm-dd' 格式的 ISO 日期字串 :
>>> str(d)
'2024-08-13'
如果要建立指定日期之 date 物件, 可以呼叫 datetime.date 類別的建構子 date() 並傳入 year, month, 與 day 三個參數即可 :
datetime.date(year, month, day)
例如 2024 年的元旦 :
>>> d=date(2024, 1, 1)
>>> type(d)
<class 'datetime.date'>
用 dir() 檢視 date 物件成員 :
>>> dir(d)
['__add__', '__class__', '__delattr__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__gt__', '__hash__', '__init__', '__init_subclass__', '__le__', '__lt__', '__ne__', '__new__', '__radd__', '__reduce__', '__reduce_ex__', '__repr__', '__rsub__', '__setattr__', '__sizeof__', '__str__', '__sub__', '__subclasshook__', 'ctime', 'day', 'fromisocalendar', 'fromisoformat', 'fromordinal', 'fromtimestamp', 'isocalendar', 'isoformat', 'isoweekday', 'max', 'min', 'month', 'replace', 'resolution', 'strftime', 'timetuple', 'today', 'toordinal', 'weekday', 'year']
用上面的自訂模組 members 之 list_members() 檢視 date 物件成員 :
>>> list_members(d)
ctime <class 'builtin_function_or_method'>
day <class 'int'>
fromisocalendar <class 'builtin_function_or_method'>
fromisoformat <class 'builtin_function_or_method'>
fromordinal <class 'builtin_function_or_method'>
fromtimestamp <class 'builtin_function_or_method'>
isocalendar <class 'builtin_function_or_method'>
isoformat <class 'builtin_function_or_method'>
isoweekday <class 'builtin_function_or_method'>
max <class 'datetime.date'>
min <class 'datetime.date'>
month <class 'int'>
replace <class 'builtin_function_or_method'>
resolution <class 'datetime.timedelta'>
strftime <class 'builtin_function_or_method'>
timetuple <class 'builtin_function_or_method'>
today <class 'builtin_function_or_method'>
toordinal <class 'builtin_function_or_method'>
weekday <class 'builtin_function_or_method'>
year <class 'int'>
可見 date 物件有非常多屬性與方法可用, 常用屬性與方法如下表 :
date 物件屬性 | 說明 |
year | 年 |
month | 月 |
day | 日 |
例如 :
>>> d.year
2024
>>> d.month
1
>>> d.day
1
常用方法如下表 :
date 物件常用方法 | 說明 |
strftime(str) | 依據格式字串 str (例如 '%Y-%m-%d') 傳回日期字串 |
replace([year, month, day]) | 依據傳入參數更改 date 物件之年/月/日 |
ctime() | 傳回日期與時間字串 (時間固定為 00:00:00) |
weekday() | 傳回此日為一周中的星期幾 (0~6), 星期一為 0 |
isoweekday() | 傳回此日為一周中的星期幾 (0~6), 星期一為 1 |
isocalendar() | 傳回 (年, 一年第幾周, ISO 的一周第幾日) tuple |
isoformat() | 傳回 ISO 格式的日期時間字串 (即 'YYYY-mm-dd') |
today() | 傳回今日之日期 |
以下測試均以 2024 年元旦的 date 物件 date(2024, 1, 1) 為例 :
strftime() 方法會依據傳入之格式化字串傳回日期字串, 不過因為 date 物件僅有日期資訊, 因此時間部分固定為 00:00:00. 可用之格式化字串如下表所示 :
format 格式化字串 | 說明 |
%a | 星期的縮寫, 例如 Sun, Mon, Tue 等 |
%A | 星期的全寫, 例如 Sunday, Monday, Tuesday 等 |
%b | 月份的縮寫, 例如 Jan, Feb, Mar 等 |
%B | 月份的全寫, 例如 January, Feburary, March 等 |
%c | 本地之日期時間, 例如 'Sun Aug 28 13:17:18 2022' |
%d | 一個月中的第幾日 (1~31) |
%H | 24 小時制的時 (0~23), 例如 13 (下午一點) |
%I | 12 小時制的時 (0~12), 例如 01 (下午一點或凌晨一點) |
%j | 一年中的第幾日 (1~366) |
%m | 數字月份 (1~12) |
%M | 分鐘 (0~59) |
%p | 上午 ('AM') 或下午 ('PM') |
%S | 秒 (0~59) |
%U | 一年中的第幾周 (0~53), 第一個星期日之前為第0 周 (週日為一周之始) |
%w | 一周中的第幾天 (0~6), 週日為 0 |
%W | 一年中的第幾周 (0~53), 第一個星期一之前為第0 周 (週一為一周之始) |
%x | 本地之日期, 格式=月/日/年(兩位), 例如 '08/28/22' |
%X | 本地之日期, 格式=時:分:秒, 例如 '14:14:48' |
%y | 無世紀之年份 (2 位數), 例如 '22' (表示 2022 年) |
%Y | 有世紀之年份 (4 位數), 例如 '2022' (表示 2022 年) |
%z | 相對於 GMT 的時區偏移值 (24 小時制), 例如台灣是 '+0800' 表示 GMT+8 |
%Z | 時區名稱 (已棄用) |
%% | 顯示 '%' 字元 |
這與 time 模組的 strftime() 方法所用之格式化字串完全相同, 參考 :
例如 :
>>> d.strftime('%Y-%m-%d')
'2024-01-01'
>>> d.strftime('%Y/%m/%d')
'2024/01/01'
ctime() 方法傳回英文的日期字串 (但時間部分固定為 00:00:00) :
>>> d.ctime()
'Mon Jan 1 00:00:00 2024'
weekday() 方法傳回此日為一周中的第幾日 (星期一為 0) :
>>> d.weekday()
0
isoweekday() 傳回 ISO 一周中的第幾日 (星期一為 1) :
>>> d.isoweekday()
1
isocalendar() 會傳回一個 IsoCalendarDate 物件, 其實就是一個由 (年份, 一年的第幾周, ISO 一周第幾日) 組成的 tuple, 例如 :
>>> d.isocalendar()
datetime.IsoCalendarDate(year=2024, week=1, weekday=1)
>>> d.isocalendar()[0]
2024
>>> d.isocalendar()[1]
1
>>> d.isocalendar()[2]
1
isoformat() 方法會傳回 'YYYY-mm-dd' 的 ISO 日期字串 :
>>> d.isoformat()
'2024-01-01'
today() 方法會傳回今日日期之 date 物件 :
>>> d
datetime.date(2024, 1, 1)
>>> d.today()
datetime.date(2024, 8, 13)
可見雖然物件 d 的日期是 2024-01-01, 但呼叫其 today() 會傳回今日日期.
replace() 方法可傳入 year, month, 或 day 來更改日期物件中的年, 月, 日, 例如 :
>>> d.replace(year=2023)
datetime.date(2023, 1, 1)
>>> d.replace(year=2024, month=7, day=23)
datetime.date(2024, 7, 23)
>>> d.replace(month=1, day=1)
datetime.date(2024, 1, 1)
二. 使用 datetime.time 類別處理時間 :
呼叫 time 類別的建構子 time() 即可建立 time 物件, 參數結構如下 :
time([hour=0, minute=0, second=0, microsecond=0, tzinfo=None])
注意, 參數 tzinfo 預設為 UTC 時間.
例如 :
>>> t=time() # 未傳入參數時間為 00:00
>>> t
datetime.time(0, 0)
>>> t=time(11, 10, 5, 1) # 指定時分秒與微秒
>>> t
datetime.time(11, 10, 5, 1)
>>> type(t)
<class 'datetime.time'>
用 dir() 檢視 time 物件內容 :
>>> dir(t)
['__class__', '__delattr__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__gt__', '__hash__', '__init__', '__init_subclass__', '__le__', '__lt__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', 'dst', 'fold', 'fromisoformat', 'hour', 'isoformat', 'max', 'microsecond', 'min', 'minute', 'replace', 'resolution', 'second', 'strftime', 'tzinfo', 'tzname', 'utcoffset']
用上面的 list_members() 檢視內容 :
>>> list_members(t)
dst <class 'builtin_function_or_method'>
fold <class 'int'>
fromisoformat <class 'builtin_function_or_method'>
hour <class 'int'>
isoformat <class 'builtin_function_or_method'>
max <class 'datetime.time'>
microsecond <class 'int'>
min <class 'datetime.time'>
minute <class 'int'>
replace <class 'builtin_function_or_method'>
resolution <class 'datetime.timedelta'>
second <class 'int'>
strftime <class 'builtin_function_or_method'>
tzinfo <class 'NoneType'>
tzname <class 'builtin_function_or_method'>
utcoffset <class 'builtin_function_or_method'>
time 物件常用屬性如下表 :
time 物件常用屬性 | 說明 |
hour | 時 |
minute | 分 |
second | 秒 |
microsecond | 微秒 |
min | 最小時間 (0, 0) |
max | 最大時間 (23, 59, 59, 999999) |
例如 :
>>> t=time(11, 10, 5, 1)
>>> t.hour
11
>>> t.minute
10
>>> t.second
5
>>> t.microsecond
1
>>> t.min
datetime.time(0, 0)
>>> t.max
datetime.time(23, 59, 59, 999999)
time 物件常用方法如下表 :
time 物件常用方法 | 說明 |
strftime(format_str) | 依據格式字串 format_str (例如 '%H-%M-%S') 傳回時間字串 |
replace([hour, minute, second]) | 依據傳入參數更改 time 物件之時/分/秒/微秒 |
fromisoformat(str) | 以 ISO 格式之時間字串 (例如 '12:34:56') 建立新的 time 物件 |
isoformat() | 傳回 ISO 格式的時間字串 (即 'HH-MM-SS') |
其中 strftime() 與 replace() 用法與上面 date 物件類似, 只是傳入參數不同. 注意, replace() 與 fromisoformat() 會傳回新的 time 物件, 不會更改原本的 time 物件內容.
例如 :
>>> t=time(hour=1, minute=23, second=56)
>>> t
datetime.time(1, 23, 56)
>>> t.strftime('%H:%M:%S')
'01:23:56'
>>> t.replace(hour=8)
datetime.time(8, 23, 56)
>>> t.replace(minute=11, second=46) # 傳回新的 time 物件
datetime.time(1, 11, 46)
>>> t.isoformat() # 原物件不受影響
'01:23:56'
>>> t.fromisoformat('01:23:45')
datetime.time(1, 23, 45)
>>> t # 原物件不受影響
datetime.time(1, 23, 56)
>>> t=t.fromisoformat('01:23:45') # 覆蓋原物件
>>> t
datetime.time(1, 23, 45)
三. 使用 datetime.timedelta 類別處理時間差 :
timedelta 類別用來處理一段時間差 (time difference) 而非某個時間點, 呼叫其建構式 timedelta() 即可建立一個時間差 timedelta 物件, 參數結構如下 :
timedelta([weeks=0, days=0, hours=0, minutes=0, seconds=0, microseconds=0])
注意, 每個關鍵字參數皆為 optional, 預設值均為 0. 最長的單位為周, 原因是周以下的長度都是固定的, 而年與月則否 (閏年與大月小月). 例如 :
>>> from datetime import timedelta
>>> delta=timedelta(weeks=1, days=2, hours=3, minutes=4, seconds=5)
>>> delta
datetime.timedelta(days=9, seconds=11045)
>>> type(delta)
<class 'datetime.timedelta'>
總天數是 7+2=9 天, 其餘 3 小時 4 分 5 秒換算成 3*60*60 + 4*60 + 5=11045 秒.
用 dir() 檢視 timedelta 物件內容 :
>>> dir(delta)
['__abs__', '__add__', '__bool__', '__class__', '__delattr__', '__dir__', '__divmod__', '__doc__', '__eq__', '__floordiv__', '__format__', '__ge__', '__getattribute__', '__gt__', '__hash__', '__init__', '__init_subclass__', '__le__', '__lt__', '__mod__', '__mul__', '__ne__', '__neg__', '__new__', '__pos__', '__radd__', '__rdivmod__', '__reduce__', '__reduce_ex__', '__repr__', '__rfloordiv__', '__rmod__', '__rmul__', '__rsub__', '__rtruediv__', '__setattr__', '__sizeof__', '__str__', '__sub__', '__subclasshook__', '__truediv__', 'days', 'max', 'microseconds', 'min', 'resolution', 'seconds', 'total_seconds']
用自訂函式 list_members() 檢視內容 :
>>> list_members(delta)
days <class 'int'>
max <class 'datetime.timedelta'>
microseconds <class 'int'>
min <class 'datetime.timedelta'>
resolution <class 'datetime.timedelta'>
seconds <class 'int'>
total_seconds <class 'builtin_function_or_method'>
timedelta 物件屬性如下表 :
timedelta 物件屬性 | 說明 |
days | 日數 |
seconds | 秒數 |
microseconds | 微秒數 |
resolution | 1 微秒的 timedelta 物件 |
min | 最小時間差 (-999999999 日) |
max | 最大時間差 (999999999 日, 86399 秒, 999999 微秒) |
例如 :
>>> delta.days
9
>>> delta.seconds
11045
>>> delta.microseconds
0
>>> delta.resolution
datetime.timedelta(microseconds=1)
>>> delta.min
datetime.timedelta(days=-999999999)
>>> delta.max
datetime.timedelta(days=999999999, seconds=86399, microseconds=999999)
timedelta 物件只有一個方法 :
timedelta 物件方法 | 說明 |
total_seconds() | 傳回總秒數 |
例如 :
>>> delta.total_seconds()
788645.0
timedelta 物件彼此可以作算術運算, 例如 :
>>> delta1=timedelta(days=30)
>>> delta1
datetime.timedelta(days=30)
>>> delta2=timedelta(weeks=2)
>>> delta2
datetime.timedelta(days=14)
>>> delta1-delta2
datetime.timedelta(days=16)
四. 使用 datetime.datetime 類別處理日期時間 :
datetime 類別主要用來處理日期時間, 並可與 timedelta 進行時間差的算術運算.
先檢視 datetime 類別內容 :
>>> from datetime import datetime
>>> dir(datetime)
['__add__', '__class__', '__delattr__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__gt__', '__hash__', '__init__', '__init_subclass__', '__le__', '__lt__', '__ne__', '__new__', '__radd__', '__reduce__', '__reduce_ex__', '__repr__', '__rsub__', '__setattr__', '__sizeof__', '__str__', '__sub__', '__subclasshook__', 'astimezone', 'combine', 'ctime', 'date', 'day', 'dst', 'fold', 'fromisocalendar', 'fromisoformat', 'fromordinal', 'fromtimestamp', 'hour', 'isocalendar', 'isoformat', 'isoweekday', 'max', 'microsecond', 'min', 'minute', 'month', 'now', 'replace', 'resolution', 'second', 'strftime', 'strptime', 'time', 'timestamp', 'timetuple', 'timetz', 'today', 'toordinal', 'tzinfo', 'tzname', 'utcfromtimestamp', 'utcnow', 'utcoffset', 'utctimetuple', 'weekday', 'year']
用自訂函式 list_members() 檢視內容 :
>>> list_members(datetime)
astimezone <class 'method_descriptor'>
combine <class 'builtin_function_or_method'>
ctime <class 'method_descriptor'>
date <class 'method_descriptor'>
day <class 'getset_descriptor'>
dst <class 'method_descriptor'>
fold <class 'getset_descriptor'>
fromisocalendar <class 'builtin_function_or_method'>
fromisoformat <class 'builtin_function_or_method'>
fromordinal <class 'builtin_function_or_method'>
fromtimestamp <class 'builtin_function_or_method'>
hour <class 'getset_descriptor'>
isocalendar <class 'method_descriptor'>
isoformat <class 'method_descriptor'>
isoweekday <class 'method_descriptor'>
max <class 'datetime.datetime'>
microsecond <class 'getset_descriptor'>
min <class 'datetime.datetime'>
minute <class 'getset_descriptor'>
month <class 'getset_descriptor'>
now <class 'builtin_function_or_method'>
replace <class 'method_descriptor'>
resolution <class 'datetime.timedelta'>
second <class 'getset_descriptor'>
strftime <class 'method_descriptor'>
strptime <class 'builtin_function_or_method'>
time <class 'method_descriptor'>
timestamp <class 'method_descriptor'>
timetuple <class 'method_descriptor'>
timetz <class 'method_descriptor'>
today <class 'builtin_function_or_method'>
toordinal <class 'method_descriptor'>
tzinfo <class 'getset_descriptor'>
tzname <class 'method_descriptor'>
utcfromtimestamp <class 'builtin_function_or_method'>
utcnow <class 'builtin_function_or_method'>
utcoffset <class 'method_descriptor'>
utctimetuple <class 'method_descriptor'>
weekday <class 'method_descriptor'>
year <class 'getset_descriptor'>
此類別有 4 個很常用的靜態方法, 毋須建立物件即可呼叫 :
datetime 類別常用靜態方法 | 說明 |
today() | 傳回今日之日期時間物件 |
now() | 傳回現在之日期時間物件 |
strptime(datetime_str, format_str) | 將日期時間字串依據格式化字串轉成 datetime 物件 |
fromtimestamp(stamp) | 將時戳轉成 datetime 物件 |
這 4 個靜態方法都會傳回一個 datetime 物件, 例如 :
>>> datetime.today()
datetime.datetime(2024, 8, 14, 23, 22, 54, 895153)
>>> datetime.now()
datetime.datetime(2024, 8, 14, 23, 23, 11, 207245)
>>> datetime.strptime('2024-08-14', '%Y-%m-%d')
datetime.datetime(2024, 8, 14, 0, 0)
>>> datetime.strptime('2024-08-14 23:23:11', '%Y-%m-%d %H:%M:%S')
datetime.datetime(2024, 8, 14, 23, 23, 11)
>>> datetime.fromtimestamp(1723704694)
datetime.datetime(2024, 8, 15, 14, 51, 34)
可見其實 today() 與 now() 會傳回相同結果. 傳給 fromtimestamp() 的時戳可用 time 模組的 time() 方法查得 :
>>> import time
>>> time.time()
1723704694.3911824
也可以呼叫建構子 datetime() 並傳入日期與時間參數來建立 datetime 物件 :
datetime(year, month, day [, hour=0, minute=0, second=0, microsecond=0, tzinfo=None])
注意, 此建構式必須傳入年月日這 3 個必要位置/關鍵字參數, 其餘時分秒微秒等參數可有可無, 例如 :
>>> dt=datetime(2024, 8, 14) # 傳入位置參數 (順序為年, 月, 日)
>>> dt
datetime.datetime(2024, 8, 14, 0, 0)
>>> dt=datetime(year=2024, month=8, day=14) # 傳入關鍵字參數 (順序可變)
>>> dt
datetime.datetime(2024, 8, 14, 0, 0)
>>> datetime(2024, 8, 14, 23, 49, 23) # 有傳入時分秒
datetime.datetime(2024, 8, 14, 23, 49, 23)
>>> datetime(2024, 8, 14, 23, 49, 23, 45634) # 有傳入微秒
datetime.datetime(2024, 8, 14, 23, 49, 23, 45634)
用 dir() 檢視 datetime 物件內容 :
>>> dir(dt)
['__add__', '__class__', '__delattr__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__gt__', '__hash__', '__init__', '__init_subclass__', '__le__', '__lt__', '__ne__', '__new__', '__radd__', '__reduce__', '__reduce_ex__', '__repr__', '__rsub__', '__setattr__', '__sizeof__', '__str__', '__sub__', '__subclasshook__', 'astimezone', 'combine', 'ctime', 'date', 'day', 'dst', 'fold', 'fromisocalendar', 'fromisoformat', 'fromordinal', 'fromtimestamp', 'hour', 'isocalendar', 'isoformat', 'isoweekday', 'max', 'microsecond', 'min', 'minute', 'month', 'now', 'replace', 'resolution', 'second', 'strftime', 'strptime', 'time', 'timestamp', 'timetuple', 'timetz', 'today', 'toordinal', 'tzinfo', 'tzname', 'utcfromtimestamp', 'utcnow', 'utcoffset', 'utctimetuple', 'weekday', 'year']
用 list_members() 檢視 datetime 物件內容 :
>>> list_members(dt)
astimezone <class 'builtin_function_or_method'>
combine <class 'builtin_function_or_method'>
ctime <class 'builtin_function_or_method'>
date <class 'builtin_function_or_method'>
day <class 'int'>
dst <class 'builtin_function_or_method'>
fold <class 'int'>
fromisocalendar <class 'builtin_function_or_method'>
fromisoformat <class 'builtin_function_or_method'>
fromordinal <class 'builtin_function_or_method'>
fromtimestamp <class 'builtin_function_or_method'>
hour <class 'int'>
isocalendar <class 'builtin_function_or_method'>
isoformat <class 'builtin_function_or_method'>
isoweekday <class 'builtin_function_or_method'>
max <class 'datetime.datetime'>
microsecond <class 'int'>
min <class 'datetime.datetime'>
minute <class 'int'>
month <class 'int'>
now <class 'builtin_function_or_method'>
replace <class 'builtin_function_or_method'>
resolution <class 'datetime.timedelta'>
second <class 'int'>
strftime <class 'builtin_function_or_method'>
strptime <class 'builtin_function_or_method'>
time <class 'builtin_function_or_method'>
timestamp <class 'builtin_function_or_method'>
timetuple <class 'builtin_function_or_method'>
timetz <class 'builtin_function_or_method'>
today <class 'builtin_function_or_method'>
toordinal <class 'builtin_function_or_method'>
tzinfo <class 'NoneType'>
tzname <class 'builtin_function_or_method'>
utcfromtimestamp <class 'builtin_function_or_method'>
utcnow <class 'builtin_function_or_method'>
utcoffset <class 'builtin_function_or_method'>
utctimetuple <class 'builtin_function_or_method'>
weekday <class 'builtin_function_or_method'>
year <class 'int'>
datetime 物件常用屬性如下表 :
datetime 物件常用屬性 | 說明 |
year | 年 |
month | 月 |
day | 日 |
hour | 時 |
minute | 月 |
second | 日 |
microsecond | 年 |
min | 最小值 |
max | 最大值 |
例如 :
>>> dt=datetime.today()
>>> dt
datetime.datetime(2024, 8, 15, 9, 47, 50, 323888)
>>> dt.year
2024
>>> dt.month
8
>>> dt.day
15
>>> dt.hour
9
>>> dt.minute
47
>>> dt.second
50
>>> dt.microsecond
323888
>>> dt.min
datetime.datetime(1, 1, 1, 0, 0)
>>> dt.max
datetime.datetime(9999, 12, 31, 23, 59, 59, 999999)
datetime 物件常用方法如下表 :
datetime 物件常用方法 | 說明 |
strftime(format_str) | 依據格式字串 (例如 '%Y-%m-%d %H:%M:%S') 傳回日期時間字串 |
strptime(dt_str, format_str) | 將日期時間字串 dt_str 依格式字串 format_str 解析傳回 datetime 物件 |
replace([year, month, ...]) | 依據傳入日期時間參數更改 datetime 物件之年/月/日/時/分/秒/微秒 |
ctime() | 傳回日期與時間字串 |
weekday() | 傳回此日為一周中的星期幾 (0~6), 星期一為 0 |
isoweekday() | 傳回此日為一周中的星期幾 (0~6), 星期一為 1 |
isocalendar() | 傳回 (年, 一年第幾周, ISO 的一周第幾日) tuple |
isoformat() | 傳回 ISO 格式的日期時間字串 (即 'YYYY-mm-ddTHH:MM::SS.uuuuu') |
today() | 傳回今日之日期時間 (即時) |
now() | 傳回現在之日期時間 (即時) |
timetuple() | 傳回 |
例如 :
>>> dt=datetime.today() # 或用 now() 亦可
>>> dt.ctime() # 英文日期時間
'Thu Aug 15 10:04:35 2024'
>>> dt.weekday() # 星期四傳回 3
3
>>> dt.isoweekday() # 星期四傳回 4
4
>>> dt.isoformat()
'2024-08-15T10:04:35.271479'
>>> dt.isocalendar()
datetime.IsoCalendarDate(year=2024, week=33, weekday=4)
>>> dt.today() # 與 dt 物件無關的即時日期時間
datetime.datetime(2024, 8, 15, 10, 8, 36, 315497)
>>> dt.now() # 與 dt 物件無關的即時日期時間
datetime.datetime(2024, 8, 15, 10, 9, 21, 897006)
>>> dt.timetuple()
time.struct_time(tm_year=2024, tm_mon=8, tm_mday=15, tm_hour=10, tm_min=4, tm_sec=35, tm_wday=3, tm_yday=228, tm_isdst=-1)
>>> dt.replace(year=2023, day=24) # 更改年, 日
datetime.datetime(2023, 8, 24, 10, 4, 35, 271479)
>>> dt.replace(hour=20, second=59) # 更改時, 秒
datetime.datetime(2024, 8, 15, 20, 4, 59, 271479)
在實務中最常用的方法是 strftime() 與 strptime(), 兩者互為反運算, strftime() 將 datetime 物件依照格式化字串之格式輸出; 後者則是將日期時間字串依照格式化字串轉成 datetime 物件, 例如 :
>>> dt.strftime('%Y-%m-%d %H:%M:%S.%f')
'2024-08-15 10:04:35.271479'
>>> dt.strftime('%I:%M %p')
'10:04 AM'
>>> dt.strftime('%B of %y')
'August of 24'
>>> dt.strptime('2024-08-15 10:04:35.271479', '%Y-%m-%d %H:%M:%S.%f')
datetime.datetime(2024, 8, 15, 10, 4, 35, 271479)
>>> dt.strptime('10:04:35', '%H:%M:%S') # 未指定年月日預設 1900/1/1
datetime.datetime(1900, 1, 1, 10, 4, 35)
>>> dt.strptime('August 15, 2024', '%B %d, %Y')
datetime.datetime(2024, 8, 15, 0, 0)
注意, 雖然 strftime() 與 strptime() 都同時定義在 datetime.datetime 類別中, 但只有 strptime() 是可以在不建立物件情況下直接呼叫的靜態方法, strftime() 則是必須先建立物件才能呼叫的物件方法, 例如上面將 '2024-08-15 10:04:35.271479' 轉成 datetime 物件的範例也可以直接呼叫 datetime.strptime() :
>>> from datetime import datetime
>>> datetime.strptime('2024-08-15 10:04:35.271479', '%Y-%m-%d %H:%M:%S.%f')
datetime.datetime(2024, 8, 15, 10, 4, 35, 271479)
但如果要將 datetime 物件格式化為日期時間字串, 那前提必須是已建立了 datetime 物件.
datetime 物件之間可以進行算術運算, 兩個 datetime 物件相減會傳回一個 timedelta 物件 :
>>> dt1=datetime(2024, 1, 1)
>>> dt1
datetime.datetime(2024, 1, 1, 0, 0)
>>> dt2=datetime(2024, 8, 15)
>>> dt2
datetime.datetime(2024, 8, 15, 0, 0)
>>> dt2-dt1 # 兩個 datetime 物件相減得到 timedelta 物件
datetime.timedelta(days=227) # 元旦至 8/15 差距為 227 天
>>> type(dt2-dt1)
<class 'datetime.timedelta'>
datetime 物件最方便的功能是可以搭配 timedelta 物件進行時間差的算術運算 :
>>> dt=datetime.today()
>>> dt
datetime.datetime(2024, 8, 15, 12, 46, 12, 194439)
>>> dt + timedelta(hours=3)
datetime.datetime(2024, 8, 15, 15, 46, 12, 194439)
>>> dt - timedelta(days=3)
datetime.datetime(2024, 8, 12, 12, 46, 12, 194439)
>>> dt - timedelta(weeks=1)
datetime.datetime(2024, 8, 8, 12, 46, 12, 194439)
如果要計算 100 天後的日期是哪天, 可以將今日之 datetime 物件加上 timedelta(days=100) :
>>> datetime.today()
datetime.datetime(2024, 8, 15, 14, 58, 12, 696363)
>>> datetime.today() + timedelta(days=100)
datetime.datetime(2024, 11, 23, 14, 58, 33, 754958)
可見 8/15 的 100 天後為 11/23 日.
沒有留言:
張貼留言