前提
Pythonで日時データを扱う場合は、以下のように標準ライブラリをインポートしてください。
from datetime import datetime, date, timedelta
datetime
には、以下の6つのオブジェクトがあります。
date
time
datetime
timedelta
tzinfo
timezone
それぞれのオブジェクトに関数があります。
例)datetime.now
(現在の日時を返します)
現在日時の取得
ローカル時間
datetime.now()
from datetime import datetime print(datetime.now())
date.today()
となります。ISOフォーマットでローカル時間を取得
datetime.now().isoformat()
from datetime import datetime print(datetime.now()) # 2020-09-03 13:21:15.119893 print(datetime.now().isoformat()) # 2020-09-03T13:21:15.120359
datetimeのtimezoneを使ってタイムゾーン指定
datetime.now(timezone.utc)
from datetime import datetime, timezone, timedelta print(timezone.utc) # UTC print(datetime.now(timezone.utc)) # 2020-09-03 04:27:44.509358+00:00
datetimeのtimezoneでタイムゾーン指定(時差を指定
timedeltaでタイムゾーンの時間の加減を作成し、その値をtimezoneに渡します。
from datetime import datetime, timedelta, timezone tz_jst = timedelta(hours=9) print(tz_jst) # 9:00:00 tz_jst = timezone(timedelta(hours=9)) print(tz_jst) # UTC+09:00 print(datetime.now(timezone(timedelta(hours=9)))) # 2020-07-13 08:47:58.787957+09:00
pytzを使ってタイムゾーン指定(エリア指定
from datetime import datetime from pytz import timezone print(datetime.now(timezone('America/New_York'))) # 2020-05-17 02:14:08.276386-04:00
'UTC'
'Europe/London'
'America/New_York'
'Asia/Tokyo'
その他はWiKiを参照してください。タイムゾーンの追加・変換
タイムゾーンの追加
タイムゾーンが設定されていない日時に対して、タイムゾーンを追加します。
これは単に追加するだけで、タイムゾーンを追加することによって日時が変わるものではありません。
タイムゾーンの追加は、replace()
とlocalize()
を利用できますが、localize()を使いましょう。
replace()
の場合、+09:19
や-04:56
などと挙動がおかしいようです。
localize()
の場合は、サマータイムでありえない時間になる可能性があります。
本ページの下部にある別項目の「サマータイムによる日時の修正(存在しない日時になる問題)」を参照してください。
from datetime import datetime, date, timedelta from pytz import timezone # ------------------------------------------- # 現在日時を設定 now_date = datetime.now() print(now_date) # 2020-09-12 14:02:06.259781 print(now_date.tzinfo) # None # ------------------------------------------- # 各タイムゾーンを設定 utc_timezone = timezone('UTC') jp_timezone = timezone('Asia/Tokyo') ny_timezone = timezone('America/New_York') # ------------------------------------------- # 以下は、挙動がおかしい。 print(now_date.replace(tzinfo=utc_timezone)) # 2020-09-12 14:02:06.259781+00:00 print(now_date.replace(tzinfo=jp_timezone)) # 2020-09-12 14:02:06.259781+09:19 print(now_date.replace(tzinfo=ny_timezone)) # 2020-09-12 14:02:06.259781-04:56 # ------------------------------------------- # 以下は、正確にタイムゾーンを付与できている。 print(utc_timezone.localize(now_date)) # 2020-09-12 14:02:06.259781+00:00 print(jp_timezone.localize(now_date)) # 2020-09-12 14:02:06.259781+09:00 print(ny_timezone.localize(now_date)) # 2020-09-12 14:02:06.259781-04:00
タイムゾーンの変換
タイムゾーンを追加または変換する際に、時間を変更します。
もし時間を変更せずにタイムゾーンを変換したい場合は、一旦タイムゾーンを削除してからlocalize()
でタイムゾーンを追加してください。詳しくは次の項目の「タイムゾーンの削除」を参照してください。
from datetime import datetime, date, timedelta from pytz import timezone # ------------------------------------------- # 現在日時を設定 now_date = datetime.now() print(now_date) # 2020-09-12 14:02:06.259781 print(now_date.tzinfo) # None # ------------------------------------------- # 各タイムゾーンを設定 utc_timezone = timezone('UTC') jp_timezone = timezone('Asia/Tokyo') ny_timezone = timezone('America/New_York') # ------------------------------------------- print(now_date.astimezone(utc_timezone)) # 2020-09-12 05:02:06.259781+00:00 print(now_date.astimezone(jp_timezone)) # 2020-09-12 14:02:06.259781+09:00 print(now_date.astimezone(ny_timezone)) # 2020-09-12 01:02:06.259781-04:00
タイムゾーンの削除
replace(tzinfo=None)
でタイムゾーンを削除することが可能です。
以下の例は、タイムゾーンを削除し、その後、別のタイムゾーンに設定しています。これで時間を変えずにタイムゾーンを変更することが可能です。
jp_date = now_date.astimezone(jp_timezone) print(jp_date) # 2020-09-12 14:02:06.259781+09:00 jp_date = jp_date.replace(tzinfo=None) print(jp_date) # 2020-09-12 14:02:06.259781 print(ny_timezone.localize(jp_date)) # 2020-09-12 14:02:06.259781-04:00
サマータイムによる日時の修正(存在しない日時になる問題)
例えば2020年のニューヨークのサマータイムは、3月8日午前2時から開始され、1時間早まります。
1時間早まることによって午前2時は3時になります。
午前2時から3時までの1時間は、存在しない時間となる訳です。
localize()
でタイムゾーンを追加した場合、このサマータイムの時差の存在の有無は考慮されません。
localize()
でタイムゾーンを追加した値を、normalize()
またはastimezone()
で再度変換すると正しい時間とタイムゾーンになります。
now_date = datetime(2020, 3, 8, 2, 30, 0, 0) print(now_date) ny_date = ny_timezone.localize(now_date) print(ny_date) # 2020-03-08 02:30:00-05:00 print(ny_timezone.normalize(ny_date)) # 2020-03-08 03:30:00-04:00 print(ny_date.astimezone(ny_timezone)) # 2020-03-08 03:30:00-04:00
指定した日時で日時データを作成
日付データ
datetime
のdate
を使用します。
date(year, month, day)
from datetime import date print(date(2020, 1, 1)) # 2020-01-01
日時データ
datetime
のdatetime
を使用します。
datetime(year, month, day, hour=0, minute=0, second=0, microsecond=0, tzinfo=None, *, fold=0)
year
,month
,day
引数は必須です。day
:上限値は、月末は指定した年と月によるhour
:0〜24minute
:0〜60second
:0〜60microsecond
:0〜1000000tzinfo
:タイムゾーン形式である必要があるfold
:1回目[0]、2回目[1]、指定された日時が何回目を指定する。サマータイムがある地域では同じ時間が存在するためである。例えばアメリカで午前2時にサマータイムが終了すると1時間戻るため午前1時になり、この午前1時〜午前2時が2回存在することになります。
from datetime import datetime, timedelta, timezone print(datetime(2020, 1, 1)) # 2020-01-01 00:00:00 print(datetime(2020, 1, 1, 13, 15, 30)) # 2020-01-01 13:15:30 print(datetime(2020, 1, 1, 13, 15, 30, 12)) # 2020-01-01 13:15:30.000012 print(datetime(2020, 1, 1, 13, 15, 30, 12, timezone(timedelta(hours=9)))) # 2020-01-01 13:15:30.000012+09:00
日時データから値を取得
日時データから年・月・日・時・分・秒などを取得することができます。
datetime.now().date()で
年月日を、datetime.now().time()
で時間を取得することもできます。
曜日は、datetime.now().weekday()で取得できますが、月曜日を0、日曜日を6として、数値で返します。
from datetime import datetime print(datetime.now()) # 2020-09-03 13:08:35.306813 # 年月日 print(datetime.now().date()) # 2020-09-03 # 時間 print(datetime.now().time()) # 13:08:35.306813 # 年 print(datetime.now().year) # 2020 # 月 print(datetime.now().month) # 9 # 日 print(datetime.now().day) # 3 # 時 print(datetime.now().hour) # 13 # 分 print(datetime.now().minute) # 8 # 秒 print(datetime.now().second) # 35 # 曜日 print(datetime.now().weekday()) # 3
その他の取得できる値は以下を参照してください。
文字列を日時データに変換
文字列を日時データに変換する場合は、datetime.strptime
を使います。
日時データ
from datetime import datetime tstr = "2020-04-01 12:34:56" tdatetime = datetime.strptime(tstr, '%Y-%m-%d %H:%M:%S') print(tdatetime) # 2020-04-01 12:34:56 print(type(tdatetime)) # <class 'datetime.datetime'>
"2020-04-01 12:34:56"
が例えば"2020/04/01 12:34:56"
のように形式が異なるとエラーになります。ミリ秒がついている場合は
'%Y-%m-%d %H:%M:%S.%f'
とします。タイムゾーン付日時データ
以下の例は、Oandaのデータ形式になっています。
from datetime import datetime tstr = "2020-04-01 12:34:56+00:00" tdatetime = datetime.strptime(tstr, '%Y-%m-%d %H:%M:%S%z') # ミリ秒とタイムゾーン print(tdatetime) # 2020-04-01 12:34:56+00:00 print(type(tdatetime)) # <class 'datetime.datetime'>
日時データを文字列に変換
日時データを文字列に変換するにはdatetime.strftime
を使います。
from datetime import datetime tstr = "2020-04-01 12:34:56+00:00" tdatetime = datetime.strptime(tstr, '%Y-%m-%d %H:%M:%S%z') # ミリ秒とタイムゾーン print(tdatetime) # 2020-04-01 12:34:56+00:00 print(tdatetime.strftime('%Y/%m/%d')) # 2020-04-01 12:34:56
datetime.strptime
と一文字違いなので注意してください。
日時データを文字列に変換する場合、フォーマットを自由に決めることができ、また欲しい情報のみを取り出すことができます。
書式コードは以下のドキュメントを参照してください。
https://docs.python.org/ja/3.6/library/datetime.html#strftime-and-strptime-behavior
タイムスタンプの変換
日時(DITETIME)をタイプスタンプ(UNIX TIME STAMP)に変換
少し前座が長くなっていますが、datetime.timestamp()
だけで変換します。
from datetime import datetime tstr = "2020-04-01 12:34:56" tdatetime = datetime.strptime(tstr, '%Y-%m-%d %H:%M:%S') print(tdatetime) # 2020-04-01 12:34:56 print(type(tdatetime)) # <class 'datetime.datetime'> print(tdatetime.timestamp()) # 1585712096.0
タイプスタンプ(UNIX TIME STAMP)を日時(DITETIME)に変換
from datetime import datetime print(datetime.fromtimestamp(1585712096.0)) # 2020-04-01 12:34:56
ミリ秒がある13桁のタイムスタンプではエラーになります。
ミリ秒がある13桁の場合は、1000で割ってから変換してください。
タイプスタンプ(UNIX TIME STAMP)にタイムゾーンをつけた日時(DITETIME)に変換
from pytz import timezone
を利用し、タイムゾーンを指定します。
from datetime import datetime from pytz import timezone print(datetime.fromtimestamp(1585712096, timezone('America/New_York'))) # 2020-03-31 23:34:56-04:00
経過時間や過去の時間の計算
timedelta
を用いて経過などを算出します。
from datetime import datetime, timedelta now = datetime.now() print(now) # 2020-05-17 15:51:51.504101 # 1分後 print(now + timedelta(minutes=1)) # 2020-05-17 15:52:51.504101 # 1分前 print(now + timedelta(minutes=-1)) # 2020-05-17 15:50:51.504101
他にも以下のように指定できます。
weeks | 週 |
days | 日 |
hours | 時間 |
minutes | 分 |
seconds | 秒 |
milliseconds | ミリ秒 |
microseconds | マイクロ秒 |
1分30秒後などの場合は、timedelta(minutes=1, seconds=30)
と指定します。
年月は指定できません。次のようにします。
年月
年月の経過や過去の日付を取得するには、dateutil.relativedelta
を使用します。
from datetime import datetime from dateutil.relativedelta import relativedelta now = datetime.now() print(now) # 2020-05-17 15:58:12.532957 # 1ヶ月後 print(now + relativedelta(months=1)) # 1ヶ月前 print(now - relativedelta(months=1))
dateutil.relativedelta
では、他にも以下を使用できます。
- Year
- Month
- Day
- Hours
- Minutes
- Seconds
- Microseconds
こちらも、relativedelta(hours=1, day=1)
のように指定ができます。
timedelta
を使う意味がないように思えますね。。。
時間の差分
from datetime import datetime dt1 = datetime.strptime("2020-04-01 12:00:00", '%Y-%m-%d %H:%M:%S') dt2 = datetime.strptime("2020-04-01 12:30:00", '%Y-%m-%d %H:%M:%S') diff = dt2 - dt1 print(diff) # 0:30:00 print(diff.seconds) # 1800
days
, seconds
, microseconds
分などで取得したい場合は、以下のように計算するしか方法はありません。print(diff.seconds / 60)
営業日(翌営業日など
翌営業日などは、pandasのDateOffsetにあるBusinessDay
またはBday
を利用すれば簡単に出力することができます。Bday
はBusinessDay
のエイリアスです。
ただし、祝日は考慮されていません。
以下の例は、当日の曜日は3となっていますので木曜日になり、その2営業日後を算出います。
from datetime import date from pandas.tseries.offsets import BusinessDay today = date.today() print(today, today.weekday()) # 2020-09-03 3 nextday = today + BusinessDay(2) print(nextday) # 2020-09-07 00:00:00 print(nextday.date()) # 2020-09-07
アメリカの営業日の計算
pandasのCustomBusinessDay
とUSFederalHolidayCalendar
を使います。
USFederalHolidayCalendar
はpandasが用意した唯一のカレンダーになります。
そのアメリカのカレンダーをCustomBusinessDay
にセットします。
from datetime import date from pandas.tseries.offsets import CustomBusinessDay from pandas.tseries.holiday import USFederalHolidayCalendar today = date(2020, 9, 3) print(today, today.weekday()) # 2020-09-03 3 cday = CustomBusinessDay(calendar=USFederalHolidayCalendar()) nextday = today + cday*2 print(nextday) # 2020-09-08 00:00:00
日本の営業日の計算
日本の場合、pandasのCustomBusinessDay
を使うのは同じですが、カレンダーはjpholidayを使用します。
jpholiday.year_holidays(2020)
上記のように祝日のカレンダーを取得し日付をリスト型に変換します。jpholiday
については次の項目の祝日を参照してください。
from datetime import date from pandas.tseries.offsets import CustomBusinessDay import jpholiday today = date(2020, 9, 17) print(today, today.weekday()) # 2020-09-17 3 JapanHolidayCalendar = [val[0] for val in jpholiday.year_holidays(2020)] cday = CustomBusinessDay(holidays=JapanHolidayCalendar) nextday = today + cday*2 print(nextday) # 2020-09-23 00:00:00
祝日
日本
jpholiday
というライブラリを利用します。
import jpholiday
標準ではないのでインストールが必要になります。
例)pip install jpholiday
一覧
以下では、2020年の祝日一覧を取得します。
print(jpholiday.year_holidays(2020)) # [(datetime.date(2020, 1, 1), '元日'), (datetime.date(2020, 1, 13), '成人の日'), (datetime.date(2020, 2, 11), '建国記念の日'), (datetime.date(2020, 2, 23), '天皇誕生日'), (datetime.date(2020, 2, 24), '天皇誕生日 振替休日'), (datetime.date(2020, 3, 20), '春分の日'), (datetime.date(2020, 4, 29), '昭和の日'), (datetime.date(2020, 5, 3), '憲法記念日'), (datetime.date(2020, 5, 4), 'みどりの日'), (datetime.date(2020, 5, 5), 'こどもの日'), (datetime.date(2020, 5, 6), '憲法記念日 振替休日'), (datetime.date(2020, 7, 23), '海の日'), (datetime.date(2020, 7, 24), 'スポーツの日'), (datetime.date(2020, 8, 10), '山の日'), (datetime.date(2020, 9, 21), '敬老の日'), (datetime.date(2020, 9, 22), '秋分の日'), (datetime.date(2020, 11, 3), '文化の日'), (datetime.date(2020, 11, 23), '勤労感謝の日')]
祝日名を取得
print(jpholiday.is_holiday_name(date(2020, 1, 1))) # 元日
date
はdatetime
ライブラリのdate
になりますのでインポートを忘れないようにしてください。祝日か判断
if jpholiday.is_holiday(date(2020, 1, 1)) is False: print("NO")
in not False
としてください。