この記事は全部俺 Advent Calendar 2018の7日目の記事です。
Pythonの日付関連の処理についてまとめます。
Pythonの日付処理チートシート
パース編(文字列 → 日付型)
フォーマットが明確なとき
from datetime import datetime
datetime.strptime("20181207", "%Y%m%d") # => datetime.datetime(2018, 12, 7, 0, 0)
datetime.strptime("20181207123456", "%Y%m%d%H%M%S") # => datetime.datetime(2018, 12, 7, 12, 34, 56)
datetime.strptime("2018/12/7 12:34:56.123", "%Y/%m/%d %H:%M:%S.%f") # => datetime.datetime(2018, 12, 7, 12, 34, 56, 123000)
datetime.strptime("2018-12-07T12:34:56.123456Z", "%Y-%m-%dT%H:%M:%S.%f%z") # => datetime.datetime(2018, 12, 7, 12, 34, 56, 123456, tzinfo=datetime.timezone.utc)
datetime.strptime("Fri, 7 Dec 2018 12:34:56 GMT", "%a, %d %b %Y %H:%M:%S %Z") # => datetime.datetime(2018, 12, 7, 12, 34, 56)
参考:日付フォーマットの詳細については、こちらを参照してください。
雑にパースしたいとき/フォーマットが明確でないとき
from dateutil import parser
parser.parse("20181207") # => datetime.datetime(2018, 12, 7, 0, 0)
parser.parse("20181207123456" ) # => datetime.datetime(2018, 12, 7, 12, 34, 56)
parser.parse("2018/12/7 12:34:56.123") # => datetime.datetime(2018, 12, 7, 12, 34, 56, 123000)
parser.parse("2018-12-07T12:34:56.123456Z") # => datetime.datetime(2018, 12, 7, 12, 34, 56, 123456, tzinfo=tzutc())
parser.parse("Fri, 7 Dec 2018 12:34:56 GMT") # => datetime.datetime(2018, 12, 7, 12, 34, 56, tzinfo=tzutc())
そもそも数字ですらない文字列("yesterday"や"明日"など)をパースしたいとき
- 前提
- 実行日が日本時間で
2018/12/07
-
pip install maya
してmayaライブラリが使用できる状態であること
- 実行日が日本時間で
import maya
maya.when("yesterday").datetime() # => datetime.datetime(2018, 12, 5, 15, 42, 10, 470045, tzinfo=<UTC>)
maya.when("yesterday").local_datetime() # => datetime.datetime(2018, 12, 6, 0, 41, 6, 489476, tzinfo=<DstTzInfo 'Asia/Tokyo' JST+9:00:00 STD>)
maya.when("last month").local_datetime() # => datetime.datetime(2018, 11, 7, 0, 43, 1, 814101, tzinfo=<DstTzInfo 'Asia/Tokyo' JST+9:00:00 STD>)
maya.when("明日").local_datetime() # => datetime.datetime(2018, 12, 8, 0, 48, 42, 83341, tzinfo=<DstTzInfo 'Asia/Tokyo' JST+9:00:00 STD>)
maya.when("завтра").local_datetime() # => datetime.datetime(2018, 12, 8, 0, 50, 58, 5660, tzinfo=<DstTzInfo 'Asia/Tokyo' JST+9:00:00 STD>)
maya.when("Bukas").local_datetime() # => datetime.datetime(2018, 12, 8, 0, 53, 4, 874763, tzinfo=<DstTzInfo 'Asia/Tokyo' JST+9:00:00 STD>)
※"завтра"はロシア語。"Bukas"はタガログ語。どちらも「明日」という意味らしいです。
パース編(日付型 → 文字列型)
from datetime import datetime, timezone
datetime(2018, 12, 7).strftime("%Y%m%d") # => '20181207'
datetime(2018, 12, 7, 12, 34, 56).strftime("%Y%m%d%H%M%S") # => '20181207123456'
datetime(2018, 12, 7, 12, 34, 56, 123000).strftime("%Y/%m/%d %H:%M:%S.%f") #=> '2018/12/07 12:34:56.123000'
datetime(2018, 12, 7, 12, 34, 56, 123456, tzinfo=timezone.utc).strftime("%Y-%m-%dT%H:%M:%S.%f%z") #=> '2018-12-07T12:34:56.123456+0000'
datetime(2018, 12, 7, 12, 34, 56, tzinfo=timezone.utc).strftime("%a, %d %b %Y %H:%M:%S %Z") #=> 'Fri, 07 Dec 2018 12:34:56 UTC'
パース編(日付型同士の変換)
date, datetime, pandasの相互変換
from datetime import date, time, datetime
# datetime → date
datetime(2018, 12, 7, 12, 34, 56).date() # => datetime.date(2018, 12, 7)
# date → datetime
datetime.combine(date(2018, 12, 7), time()) # => datetime.datetime(2018, 12, 7, 0, 0)
# pandas._libs.tslibs.timestamps.Timestam → date
pd_timestamp = pd.date_range("2018/12/07", "2018/12/07")[0]
pd_timestamp.date() # => datetime.date(2018, 12, 7)
# pandas._libs.tslibs.timestamps.Timestam → datetime
datetime.combine(pd_timestamp.date(), pd_timestamp.time()) # => datetime.datetime(2018, 12, 7, 0, 0)
タイムゾーンの処理
from datetime import datetime, timezone, timedelta
jst = timezone(timedelta(hours=9), 'JST')
# ロケールの確認
import locale
locale.getlocale() # => ('ja_JP', 'UTF-8')
# ローカルでの現在時刻取得(デフォルトロケール:'ja_JP'での例)
datetime.now() # => datetime.datetime(2018, 12, 8, 11, 7, 9, 203409)
datetime.utcnow() # => datetime.datetime(2018, 12, 8, 2, 7, 10, 216128)
# タイムゾーンの設定
datetime(2018, 12, 8, 12, 34, 56).astimezone(timezone.utc) # => datetime.datetime(2018, 12, 8, 3, 34, 56, tzinfo=datetime.timezone.utc)
datetime(2018, 12, 8, 12, 34, 56).astimezone(jst) # => datetime.datetime(2018, 12, 8, 12, 34, 56, tzinfo=datetime.timezone(datetime.timedelta(0, 32400), 'JST'))
# タイムゾーンの変換
## JST → UTC
datetime.now().astimezone(jst) # => datetime.datetime(2018, 12, 8, 2, 8, 17, 143647, tzinfo=datetime.timezone.utc)
## UTC → JST
datetime.utcnow().astimezone(jst) # => datetime.datetime(2018, 12, 8, 2, 8, 56, 547187, tzinfo=datetime.timezone(datetime.timedelta(0, 32400), 'JST'))
# mayaを使用する場合
## UTC時間の取得
maya.now().datetime() # => datetime.datetime(2018, 12, 8, 2, 27, 13, 480987, tzinfo=<UTC>)
## ローカルタイムゾーンでの時刻取得
maya.now().local_datetime() # => datetime.datetime(2018, 12, 8, 11, 27, 15, 369658, tzinfo=<DstTzInfo 'Asia/Tokyo' JST+9:00:00 STD>)
演算編
日付 + 期間 or 日付 - 期間
from datetime import date, datetime
from dateutil.relativedelta import relativedelta
date(2018, 12, 7) + relativedelta(days=1) # => datetime.date(2018, 12, 8)
datetime(2018, 12, 7) + relativedelta(days=1) # => datetime.datetime(2018, 12, 8, 0, 0)
datetime(2018, 12, 7) + relativedelta(years=1, months=1, days=1) # => datetime.datetime(2020, 1, 8, 0, 0)
date(2018, 12, 7) + relativedelta(days=-1) # => datetime.date(2018, 12, 6)
date(2018, 12, 7) - relativedelta(days=1) # => datetime.date(2018, 12, 6)
月初・月末
from datetime import date, datetime
from dateutil.relativedelta import relativedelta
# 今月の月初
date(2018, 12, 7) + relativedelta(day=1) # => datetime.date(2018, 12, 1)
# 今月の月末
date(2018, 12, 7) + relativedelta(day=99) # => datetime.date(2018, 12, 31)
# 先月の月初/月末
date(2018, 12, 7) + relativedelta(months=-1, day=1) # => datetime.date(2018, 11, 1)
date(2018, 12, 7) + relativedelta(months=-1, day=99) # => datetime.date(2018, 11, 30)
# 来月の月初/月末
date(2018, 12, 7) + relativedelta(months=1, day=1) # => datetime.date(2019, 1, 1)
date(2018, 12, 7) + relativedelta(months=1, day=99) # => datetime.date(2019, 1, 31)
# datetime型も同様
datetime(2018, 12, 7) + relativedelta(months=1, day=99) # => datetime.datetime(2019, 1, 31, 0, 0)
週数の判定
from datetime import date, datetime
# その日が月の何週目にあたるのか(月曜始まり)
target_date = date(2018, 12, 7) # datetimeでも同様に処理可能
target_date.isocalendar()[1] - (target_date + relativedelta(day=1)).isocalendar()[1] + 1 # => 2
# その日が年の何周目にあたるのか(月曜始まり)
target_date.isocalendar() # => (2018, 49, 5):年, 週数, 曜日(1: 月曜、 2: 火曜...)が出力される
target_date.isocalendar()[1] # => 49
曜日の判定
from datetime import date, datetime
# 月曜始まりの定数リストを作成
WEEK = ["月", "火", "水", "木", "金", "土", "日"]
# リストから曜日を出力(weekay()は、 0: "月曜日", 1: "火曜日", ...となっている)
WEEK[date(2018, 12, 8).weekday()] # => '土'
WEEK[datetime(2018, 12, 8).weekday()] # => '土'
まとめ
mayaは、日本語の「明日」だけじゃなく、ロシア語やタガログ語も日付に変換できるぞ!
なお、使い所は不明です。一応、形態素解析と組み合わせて使える・・・のか?
今後も思いついたら適宜追加していく予定です。
指摘・修正や編集リクエストもお待ちしております!