Python 標準ライブラリ datetime 日付と時刻
Publish date: 2021-03-27
Pythonの標準にある日付と時刻を扱うためのライブラリdatetimeの解説です。
概要
datetimeモジュールには、日付や時刻を扱うための型として以下が定義されています。
- date 日付
- datetime 日時
- time 時刻
- timedelta 時間差
- tzinfo タイムゾーン(基底クラス)
- timezone タイムゾーン(UTC実装クラス)
Python3.9からはtzinfoを実装したZoneInfoがzoneinfoモジュールに用意されています。クラス図・継承関係は以下の通りです。
date 日付
dateの定義
from datetime import date
# システム日付 today()
d = date.today()
# 年月日指定 date(year, month, day)
d = date(2021, 7, 1)
# タイムスタンプ fromtimestamp(timestamp)
d = date.fromtimestamp(1616844264.2229254)
# 1年1月1日からの日数 fromordinal(ordinal)
d = date.fromordinal(1)
# YYYY-MM-DDの文字列 fromisoformat(date_string)
d = date.fromisoformat('2021-07-01')
# ISO暦(年数, 週数, 曜日) fromisocalendar(year, week, day)
d = date.fromisocalendar(2021, 15, 1)
dateで定義されている定数(最小、最大、最小の差分)
date.min #=> datetime.date(1, 1, 1)
date.max #=> datetime.date(9999, 12, 31)
date.resolution #=> datetime.timedelta(days=1)
dateの属性
d = date(2021, 7, 1)
d.year # => 2021
d.month # => 7
d.day # => 1
dateのメソッド
# replace(year=self.year, month=self.month, day=self.day) 日付の項目変更
d = date(2021, 6, 15)
d.replace(day=1) # => datetime.date(2021, 6, 1)
# timetuple() 情報のタプルでの取得
d = date(2021, 6, 15)
tt = d.timetuple()
list(tt) # => [2021, 6, 15, 0, 0, 0, 1, 166, -1]
print(tt.tm_year) # => 2021 年
print(tt.tm_mon) # => 6 月
print(tt.tm_mday) # => 15 日
print(tt.tm_hour) # => 0 時
print(tt.tm_min) # => 0 分
print(tt.tm_sec) # => 0 秒
print(tt.tm_wday) # => 1 (0:月,1:火~6:日)
print(tt.tm_yday) # => 166 年間第何日目
print(tt.tm_isdst) # => -1 夏時間 (-1:不明,1:有効,0:無効)
print(tt.tm_zone) # => None タイムゾーン
print(tt.tm_gmtoff) # => None UTCオフセット秒
# toordinal() 1年1月1日からの日付序数
d.toordinal() # => 737956
# weekday() 曜日(0起算)
d.weekday() # => 1 (月曜日0~日曜日6)
# isoweekday() 曜日(1起算)
d.isoweekday() # => 2 (月曜日1~日曜日7)
# isocalendar() ISO暦(年数, 週数, 曜日)
isoc = d.isocalendar()
list(isoc) # => [2021, 24, 2]
print(isoc.year) # => 2021 年
print(isoc.week) # => 24 週目
print(isoc.weekday) # => 2 火曜日
# isoformat() YYYY-MM-DD形式での文字列取得
d.isoformat() # => '2021-06-15'
# ctime() 文字列での日付取得
d.ctime() # => 'Tue Jun 15 00:00:00 2021'
# strftime(format) 日付のフォーマット
d.strftime('%Y-%m-%d') # => '2021-06-15'
datetime 日時
datetimeの定義
from datetime import datetime
from datetime import date
from datetime import time
from datetime import timezone
# システム日付・時刻 now(tz=None)
dt = datetime.now()
dt = datetime.now(tz=timezone.utc)
dt = datetime.now(timezone.utc)
# システム日付・時刻 today()
dt = datetime.today()
# UTCシステム日付・時刻 utcnow()
dt = datetime.utcnow()
# datetime(year, month, day, hour=0, minute=0, second=0, microsecond=0, tzinfo=None, *, fold=0)
dt = datetime(2021, 7, 1, 18, 30, 45, 123456)
# タイムスタンプ fromtimestamp(timestamp, tz=None)
dt = datetime.fromtimestamp(1616844264.2229254, tz=None)
# UTCタイムスタンプ utcfromtimestamp(timestamp)
dt = datetime.utcfromtimestamp(616844264.2229254)
# 1年1月1日からの日数 fromordinal(ordinal)
dt = datetime.fromordinal(1)
# 日付と日時の結合 combine(date, time, tzinfo=self.tzinfo)
date_part = date(2021, 7, 1)
time_part = time(23, 30, 45, 123456)
dt = datetime.combine(date_part, time_part)
# YYYY-MM-DD[*HH[:MM[:SS[.fff[fff]]]][+HH:MM[:SS[.ffffff]]]]の文字列 fromisoformat(date_string)
dt = datetime.fromisoformat('2021-07-01 18:30:55.123456+09:00:00.000000')
# ISO暦(年数, 週数, 曜日) fromisocalendar(year, week, day)
dt = datetime.fromisocalendar(2021, 15, 1)
# 文字列指定 strptime(date_string, format)
dt = datetime.strptime("2021-07-01 18:30:55.123456+090000.000000", '%Y-%m-%d %H:%M:%S.%f%z')
datetimeで定義されている定数(最小、最大、最小の差分)
datetime.min #=> datetime.datetime(1, 1, 1, 0, 0)
datetime.max #=> datetime.datetime(9999, 12, 31, 23, 59, 59, 999999)
datetime.resolution #=> datetime.timedelta(microseconds=1)
datetimeの属性
from zoneinfo import ZoneInfo
dt = datetime(2021, 7, 1, 18, 30, 45, 123456, ZoneInfo("Asia/Tokyo"))
dt.year # => 2021 年
dt.month # => 7 月
dt.day # => 1 日
dt.hour # => 18 時
dt.minute # => 30 分
dt.second # => 45 秒
dt.microsecond # => 123456 マイクロ秒
dt.tzinfo # => zoneinfo.ZoneInfo(key='Asia/Tokyo') タイムゾーン
dt.fold # => 0 夏時間 (-1:不明,1:有効,0:無効)
datetimeのメソッド
dt = datetime(2021, 7, 1, 18, 30, 45, 123456, ZoneInfo("Asia/Tokyo"))
# date() 日付
dt.date() # => datetime.date(2021, 7, 1)
# time() 時刻
dt.time() # => datetime.time(18, 30, 45, 123456)
# timetz() 時刻(タイムゾーン付き)
dt.timetz() # => datetime.time(18, 30, 45, 123456, tzinfo=zoneinfo.ZoneInfo(key='Asia/Tokyo'))
# replace(year=self.year, month=self.month, day=self.day, hour=self.hour, minute=self.minute, second=self.second, microsecond=self.microsecond, tzinfo=self.tzinfo, *, fold=0)
dt.replace(hour=19) # => datetime.datetime(2021, 7, 1, 19, 30, 45, 123456, tzinfo=zoneinfo.ZoneInfo(key='Asia/Tokyo'))
# astimezone(tz=None) タイムゾーンを指定し日時を取得
dt.astimezone(timezone.utc) # => datetime.datetime(2021, 7, 1, 9, 30, 45, 123456, tzinfo=datetime.timezone.utc)
# utcoffset() オフセット取得
dt.utcoffset() # => datetime.timedelta(seconds=32400)
# datetime.now().utcoffset() # => None タイムゾーン未設定の場合None
# dst() 夏時間修正
dt.dst() # => datetime.timedelta(0)
# tzname() タイムゾーンの名称
dt.tzname() # => 'JST'
# timetuple() 情報のタプルでの取得
dtt = dt.timetuple()
list(dtt) # => [2021, 7, 1, 18, 30, 45, 3, 182, 0]
print(dtt.tm_year) # => 2021 年
print(dtt.tm_mon) # => 7 月
print(dtt.tm_mday) # => 1 日
print(dtt.tm_hour) # => 18 時
print(dtt.tm_min) # => 30 分
print(dtt.tm_sec) # => 45 秒
print(dtt.tm_wday) # => 3 (0:月,1:火~6:日)
print(dtt.tm_yday) # => 182 年間第何日目
print(dtt.tm_isdst) # => 9 夏時間 (-1:不明,1:有効,0:無効)
print(dtt.tm_zone) # => None タイムゾーン
print(dtt.tm_gmtoff) # => None UTCオフセット秒
# utctimetuple() 情報のタプルでの取得(UTC基準)
dtt = dt.utctimetuple()
list(dtt) # =>[2021, 7, 1, 9, 30, 45, 3, 182, 0]
print(dtt.tm_year) # => 2021 年
print(dtt.tm_mon) # => 7 月
print(dtt.tm_mday) # => 1 日
print(dtt.tm_hour) # => 9 時
print(dtt.tm_min) # => 30 分
print(dtt.tm_sec) # => 45 秒
print(dtt.tm_wday) # => 3 (0:月,1:火~6:日)
print(dtt.tm_yday) # => 182 年間第何日目
print(dtt.tm_isdst) # => 0 夏時間 (-1:不明,1:有効,0:無効)
print(dtt.tm_zone) # => None タイムゾーン
print(dtt.tm_gmtoff) # => None UTCオフセット秒
# toordinal() 1年1月1日からの日付序数
dt.toordinal() # => 737972
# timestamp() タイムスタンプ
dt.timestamp() # => 1625131845.123456
# weekday() 曜日(0起算)
dt.weekday() # => 3 (0:月,1:火~6:日)
# isoweekday() 曜日(1起算)
dt.isoweekday() # => 4 (1:月,2:火~7:日)
# isocalendar() ISO暦(年数, 週数, 曜日)
isoc = dt.isocalendar()
list(isoc) # => [2021, 26, 4]
print(isoc.year) # => 2021 年
print(isoc.week) # => 26 週目
print(isoc.weekday) # => 4 木曜日
# isoformat(sep='T', timespec='auto') ISO8601書式での文字列
dt.isoformat() # => '2021-07-01T18:30:45.123456+09:00'
dt.isoformat(sep=' ') # => '2021-07-01 18:30:45.123456+09:00'
# ctime() 文字列での日付取得
dt.ctime() # => 'Thu Jul 1 18:30:45 2021'
# strftime(format) 日時のフォーマット
dt.strftime('%Y-%m-%d %H:%M:%S.%f%z') # => '2021-07-01 18:30:45.123456+0900'
time 時刻
timeの定義
from datetime import time
from zoneinfo import ZoneInfo
# time(hour=0, minute=0, second=0, microsecond=0, tzinfo=None, *, fold=0)
t = time(18, 30, 55)
t = time(18, 30, 55, 123456, ZoneInfo("Asia/Tokyo"))
# fromisoformat(time_string)
t = time.fromisoformat('18:30:55.123456+09:00:00.000000')
timeで定義されている定数(最小、最大、最小の差分)
time.min # => datetime.time(0, 0)
time.max # => datetime.time(23, 59, 59, 999999)
time.resolution # => datetime.timedelta(microseconds=1)
timeの属性
t = time(18, 30, 55, 123456, ZoneInfo("Asia/Tokyo"))
t.hour # => 18 時
t.minute # => 30 分
t.second # => 55 秒
t.microsecond # => 123456 マイクロ秒
t.tzinfo # => zoneinfo.ZoneInfo(key='Asia/Tokyo') タイムゾーン
t.fold # => 0 夏時間
timeのメソッド
# replace(hour=self.hour, minute=self.minute, second=self.second, microsecond=self.microsecond, tzinfo=self.tzinfo, *, fold=0)
t.replace(hour=19,minute=45) # => datetime.time(19, 45, 55, 123456, tzinfo=zoneinfo.ZoneInfo(key='Asia/Tokyo'))
# isoformat(timespec='auto') ISO 8601 書式の時刻
t.isoformat() # => '18:30:55.123456'
# strftime(format) 時刻のフォーマット文字列
t.strftime('%H:%M:%S.%f%z') #=> '18:30:55.123456'
# utcoffset() オフセット
t.utcoffset() # => None
# dst() 夏時間修正
t.dst() # => None
# tzname() タイムゾーンの名称
t.tzname() # => None
timedelta 時間差
timedeltaの定義
from datetime import timedelta
# timedelta(days=0, seconds=0, microseconds=0, milliseconds=0, minutes=0, hours=0, weeks=0)
td = timedelta()
td = timedelta(hours=9)
timedeltaで定義されている定数(最小、最大、最小の差分)
timedelta.min # => datetime.timedelta(days=-999999999)
timedelta.max # => datetime.timedelta(days=999999999, seconds=86399, microseconds=999999)
timedelta.resolution # => datetime.timedelta(microseconds=1)
timedeltaの属性
td = timedelta(microseconds=5*24*60*60*1000000 + 30*1000000 + 123456)
td.days # => 5
td.seconds # => 30
td.microseconds # => 123456
timedeltaのメソッド
# 差分全体を秒数換算で取得
td.total_seconds() # => 432030.123456
timedeltaの計算
# 足し算
timedelta(hours=18) + timedelta(hours=8) # => datetime.timedelta(days=1, seconds=7200)
# 引き算
timedelta(hours=2) - timedelta(minutes=30) # => datetime.timedelta(seconds=5400)
# 掛け算
timedelta(minutes=15) * 7 # => datetime.timedelta(seconds=6300)
# 割り算
timedelta(hours=2) / timedelta(minutes=30) # => 4.0
timedelta(minutes=15) / 45 # => datetime.timedelta(seconds=20)
# 割り算と切り捨の割り算
timedelta(minutes=1) / 900 # => datetime.timedelta(microseconds=66667)
timedelta(minutes=1) // 900 # => datetime.timedelta(microseconds=66666)
timedelta(hours=2) / timedelta(minutes=50) # => 2.4
timedelta(hours=2) // timedelta(minutes=50) # => 2
# 余り
timedelta(hours=2) % timedelta(minutes=50) # => datetime.timedelta(seconds=1200)
# 商と剰余
q, r = divmod(timedelta(hours=2), timedelta(minutes=50))
q # => 2
r # => datetime.timedelta(seconds=1200)
# 自身と符号反転
+timedelta(hours=1) # => datetime.timedelta(seconds=3600)
-timedelta(hours=1) # => datetime.timedelta(days=-1, seconds=82800)
# 絶対値
abs(-timedelta(minutes=120)) # => datetime.timedelta(seconds=7200)
timedeltaの表示
str(timedelta(days=5,hours=18,minutes=45,seconds=50,microseconds=123456))
# => '5 days, 18:45:50.123456'
repr(timedelta(days=5,hours=18,minutes=45,seconds=50,microseconds=123456))
# => 'datetime.timedelta(days=5, seconds=67550, microseconds=123456)'
timezone タイムゾーン
timezoneの定義
from datetime import timezone
from datetime import timedelta
# timezone(offset, name=None)
tz = timezone(timedelta(hours=9), name='Asia/Tokyo')
timezoneの属性
# UTCタイムゾーン
timezone.utc #=> datetime.timezone.utc
timezoneのメソッド
from datetime import timezone
from datetime import timedelta
from datetime import datetime
tz = timezone(timedelta(hours=9), name='Asia/Tokyo')
# utcoffset(dt) オフセット
tz.utcoffset(None) # => datetime.timedelta(seconds=32400)
# tzname(None) タイムゾーンの名称
tz.tzname(None) # => 'Asia/Tokyo'
timezone(timedelta(hours=9)).tzname(None) #=> 'UTC+09:00'
# fromutc(dt) UTC時間からの日時
dt = datetime(2021, 7, 1, 18, 30, tzinfo=tz)
tz.fromutc(dt)
# => datetime.datetime(2021, 7, 2, 3, 30, tzinfo=datetime.timezone(datetime.timedelta(seconds=32400), 'Asia/Tokyo'))
# dst(dt) 夏時間修正
tz.dst(dt) # => None
日付、日時、時刻のフォーマット書式
strftime(format)
やstrptime(date_string, format)
では日時のフォーマットを指定して呼び出しを行います。
# 日付、日時、時刻から文字列
dt = datetime(2021, 7, 1, 18, 30, 45, 123456, ZoneInfo("Asia/Tokyo"))
dt.strftime('%Y-%m-%d %H:%M:%S.%f%z') # => '2021-07-01 18:30:45.123456+0900'
# 文字列から日付、日時、時刻
datetime.strptime("2021-07-01 18:30:55.123456+090000.000000", '%Y-%m-%d %H:%M:%S.%f%z')
# => datetime.datetime(2021, 7, 1, 18, 30, 55, 123456, tzinfo=datetime.timezone(datetime.timedelta(seconds=32400)))
引数format
で使用できる書式は以下の通りです。
年
- %Y 0埋め4桁年 [0001, 0002, …, 2020, 2021, …, 9998, 9999]
- %y 0埋め世紀無し年 [00, 01, …, 99]
月
- %m 0埋め月数 [01, 02, …, 12]
- %b 短縮形の月名 [1, 2, …, 12, Jan, Feb, …, Dec ]
- %B 長い月名 [1月, 2月, …, 12月, January, February, …, December]
日
- d 0埋め日にち [01, 02, …, 31]
曜日
- %w 0起算日曜始まりの数字 [0,1,…,6]
- %a 短縮形の曜日名称 [日曜日, 月曜日, …, 土曜日, Sun, Mon, …, Sat]
- %A 長い曜日名称 [[日, 月, …, 土, Sunday, Monday, …, Saturday]
時
- %H 0埋め24時間表記時 [00, 01, …, 23]
- %I 0埋め12時間表記時 [01, 02, …, 12]
分
- %M 0埋め分 [00, 01, …, 59]
秒
- %S 0埋め秒 [00, 01, …, 59]
マイクロ秒
- %f 0埋めマイクロ秒 [000000, 000001, …, 999999]
タイムゾーン
- %z UTCオフセット±HHMM[SS[.ffffff]] ["", +0000, -0130, +1030, +123456.123456]
- %Z タイムゾーン名称 ["", UTC, GMT, JST]
その他
- %p ロケール午前午後 [午前, 午後, AM, PM]
- %j 年内の0埋め日数 [001, 002, …, 366]
- %U 年内の週番号(日曜日始まり) [00, 01, …, 53]
- %W 年内の週番号(月曜日始まり) [00, 01, …, 53]
- %c ロケールの日時表記 [2021/07/01 18:30:45, 7/1/2021 6:30:45 PM]
- %x ロケールの日付表記 [2021/07/01, 7/1/2021]
- %X ロケールの時刻表記 [18:30:45, 6:30:45 PM]