2021-03-30に投稿

Python 標準ライブラリ datetime 日付と時刻

読了目安:18分

Pythonの標準にある日付と時刻を扱うためのライブラリdatetimeの解説です。

概要

datetimeモジュールには、日付や時刻を扱うための型として以下が定義されています。

  • date 日付
  • datetime 日時
  • time 時刻
  • timedelta 時間差
  • tzinfo タイムゾーン(基底クラス)
  • timezone タイムゾーン(UTC実装クラス)

Python3.9からはtzinfoを実装したZoneInfoがzoneinfoモジュールに用意されています。クラス図・継承関係は以下の通りです。


## date 日付 ### dateの定義 ```python 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]
Originally published at marusankakusikaku.jp
ツイッターでシェア
みんなに共有、忘れないようにメモ

maru3kaku4kaku

Pythonこつこつ学習中。よく忘れる。

Crieitは誰でも投稿できるサービスです。 是非記事の投稿をお願いします。どんな軽い内容でも投稿できます。

また、「こんな記事が読みたいけど見つからない!」という方は是非記事投稿リクエストボードへ!

有料記事を販売できるようになりました!

こじんまりと作業ログやメモ、進捗を書き残しておきたい方はボード機能をご利用ください。
ボードとは?

コメント