Pythonで日時を扱うライブラリーについて、逆引き風にまとめてみました。
この記事の内容は、正確を期するように注意して記述していますが、公式の情報ではありません。
正確な情報をお求めなら公式リファレンス(参考資料#1)を参照してください。
想定する読者
ほとんどが標準モジュールについてのことですので、Python初心者の方か、日時ライブラリーのことをあまりご存じない方向けです。
(私自身まだPython歴が浅いので。)
前提
Python2はv2.7.10、Python3はv3.5.1で確認しています。
(Anaconda 4.0.0 Windows 64bit版を使用。)
Python2とPython3を特に個別に扱っていないものは、共通で使えるものです。
その場合、printについてはカッコつき表記で統一し、実行結果はPython3のものを採用しています。
サンプルコードは、主に対話環境での結果を掲載しています。
拡張モジュールのバージョンは以下の通りです。
dateutil 2.5.1
pytz 2016.2
APIの基本情報
日時に関する標準モジュールとそこに含まれる型について簡単に記載します。
詳しくは、公式リファレンス(参考資料#1)を参照してください。
本文中では、特に説明が無いものについてはfrom datetime import *を施したものとします。
標準モジュール
| モジュール | 説明 |
|---|---|
datetimeモジュール |
日時に関する標準の型と操作を提供します。 |
timeモジュール |
低レベル(システムレベル)の時間に関するユーティリティーが含まれます。 |
calendarモジュール |
主に、テキストカレンダーに関するユーティリティーが含まれます。 |
拡張モジュール
| モジュール | 説明 |
|---|---|
dateutil |
標準モジュールでは不足している日時処理を補ってくれるモジュール。 |
pytz |
タイムゾーンを扱うモジュール。詳細は後述。 |
型
| 型 | 説明 |
|---|---|
datetime.date |
日付オブジェクト。 |
datetime.datetime |
日時オブジェクト。 |
datetime.time |
時刻オブジェクト。timeモジュールと混同しないように。 |
datetime.timedelta |
2つの日時の差を表すオブジェクト。 |
datetime.tzinfo |
タイムゾーン情報の抽象基底クラス。 |
datetime.timezone |
タイムゾーン情報の固定オフセットによる実装。 |
time.struct_time |
UNIXのstruct tm(構造体)に相当する名前付きタプル。 |
datetimeモジュールの型階層は以下の通り。
※注:Python3.2未満にはtimezone型は存在しません。
object
timedelta
tzinfo
timezone
time
date
datetime
以降、本文中では型のモジュール名を省略します。
naiveとaware(タイムゾーン有無)
同じdatetimeオブジェクトでも、タイムゾーンが付いているものと付いていないものがあります。
Pythonでは、タイムゾーンが付いているdatetimeをaware(な日時)、付いていないdatetimeをnaive(な日時)と呼びます。
dateオブジェクトは常にnaive、timeオブジェクトはどちらにもなり得ます。
タイムゾーン(tzinfo)のインスタンスとして、Python3.2で追加されたtimezoneオブジェクトが利用できます。
それ以前はtzinfoの実装は標準モジュールに存在しませんでした。
そのような場合は、pytzモジュールを使います。
tzinfoの実装には、dateutilモジュールのサブモジュールtzもあります。
また、任意のオフセット値(JSTなら+09:00)でタイムゾーンを示す場合にはtimezoneで事足りますが、
タイムゾーンの処理を厳密に扱う必要がある場合は、pytzモジュールの使用が推奨されています。
pytzモジュールは、IANAタイムゾーンデータベース(オルソンデータベース)を参照します。
詳しくは、公式リファレンス(参考資料#1)を参照して下さい。
IANAタイムゾーンデータベースについては、以下の記事を参照して下さい。
tz database - Wikipedia
https://ja.wikipedia.org/wiki/Tz_database
naiveとawareの変換方法については、本編中に説明があります。
任意の日時のオブジェクトを生成する
コンストラクターにより生成できます。timeオブジェクトについては省略します。
>>> from datetime import datetime, date, timezone, timedelta
>>>
>>> datetime(2016, 7)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: Required argument 'day' (pos 3) not found
>>> datetime(2016, 7, 5)
datetime.datetime(2016, 7, 5, 0, 0)
>>> datetime(2016, 7, 5, 13)
datetime.datetime(2016, 7, 5, 13, 0)
>>> datetime(2016, 7, 5, 13, 45)
datetime.datetime(2016, 7, 5, 13, 45)
>>> datetime(2016, 7, 5, 13, 45, 27)
datetime.datetime(2016, 7, 5, 13, 45, 27)
>>> datetime(2016, 7, 5, 13, 45, 27, 123456)
datetime.datetime(2016, 7, 5, 13, 45, 27, 123456)
>>> datetime(2016, 7, 5, 13, 45, 27, 123456, timezone(timedelta(hours=+9)))
datetime.datetime(2016, 7, 5, 13, 45, 27, 123456, tzinfo=datetime.timezone(datetime.timedelta(0, 32400)))
>>>
>>> date(2016, 7)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: Required argument 'day' (pos 3) not found
>>> date(2016, 7, 5)
datetime.date(2016, 7, 5)
>>> date(2016, 7, 5, 0)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: function takes at most 3 arguments (4 given)
datetimeの7番目の要素は、マイクロ秒(1/1,000,000秒)です。
タイムスタンプから生成することもできます。
現在日時のタイムスタンプについては、次項を参照してください。
>>> datetime.fromtimestamp(12345678901.234567)
datetime.datetime(2361, 3, 22, 4, 15, 1, 234568)
>>> date.fromtimestamp(12345678901.234567)
datetime.date(2361, 3, 22)
ここで言うタイムスタンプ(float)とは、UNIX時間またはエポック秒と呼ばれる値です。
UNIX時間 - Wikipedia
https://ja.wikipedia.org/wiki/UNIX%E6%99%82%E9%96%93
UNIX時間は整数値ですが、Python上ではfloatで表されます。
小数点以下の値は、Python上ではマイクロ秒として扱われますが、例で分かる通り、floatの小数部で表されるので、精度は落ちます。
datetime.date()メソッドで、日付部分だけをdateとして取り出すことができます。
>>> from datetime import datetime, date
>>>
>>> dt = datetime.now()
>>> dt
datetime.datetime(2016, 7, 14, 14, 24, 46, 157000)
>>> dt.date()
datetime.date(2016, 7, 14)
現在日時のオブジェクトを生成する
datetime.now()は、現在日時を示すdatetimeオブジェクトを返します。
date.today()は、当日を示すdateオブジェクトを返します。
>>> from datetime import datetime, date
>>>
>>> datetime.now()
datetime.datetime(2016, 7, 14, 14, 14, 2, 900000)
>>> date.today()
datetime.date(2016, 7, 14)
timeモジュールのtime()関数で現在日時のタイムスタンプを取得できます。
タイムスタンプについては、前項を参照してください。
>>> import time
>>>
>>> time.time()
1468473337.565 # 2016-07-14 14:15:37.565000
他にも、timeモジュールにstruct_timeを返す(古風な)関数がいくつかありますが、今回は扱いません。
time.gmtime()関数あたりの説明を読んでみて下さい。
文字列から日時・日付へ変換
datetimeモジュールでは、datetime.strptime()関数を使います。
ただし、以下の結果を見てもらうと分かる通り、この関数は融通が利きません。
>>> from datetime import datetime, timezone, timedelta
>>> datetime.strptime("2016/07/05 13:45:06", "%Y/%m/%d %H:%M:%S")
datetime.datetime(2016, 7, 5, 13, 45, 6)
>>> datetime.strptime("2016/07/05 13:45", "%Y/%m/%d %H:%M:%S")
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "...\lib\_strptime.py", line 500, in _strptime_datetime
tt, fraction = _strptime(data_string, format)
File "...\lib\_strptime.py", line 337, in _strptime
(data_string, format))
ValueError: time data '2016/07/05 13:45' does not match format '%Y/%m/%d %H:%M:%S'
(※トレース内容は一部加工しています。)
dateutilモジュールのサブモジュールparserのparse()関数が強力なので、そちらを使いましょう。
>>> from dateutil.parser import parse
>>>
>>> parse("Tue Aug 23 17:00:35 JST 2016")
datetime.datetime(2016, 8, 23, 17, 0, 35)
>>> parse("2016-07-03T11:22:33Z")
datetime.datetime(2016, 7, 3, 11, 22, 33, tzinfo=tzutc())
>>> parse("2016/07/03 04:05:06")
datetime.datetime(2016, 7, 3, 4, 5, 6)
>>> parse("2016/07/03")
datetime.datetime(2016, 7, 3, 0, 0)
なお、Python2の場合、下記のようなエラーが出ました。
.../dateutil/parser.py:598: UnicodeWarning: Unicode equal comparison failed to convert both arguments to Unicode - interpreting them as being unequal
elif res.tzname and res.tzname in time.tzname:
この↓記事に書いてあるissueに関係ありそうなんですが、dateutilのバージョンが2.5.1なのに発生しているんですよね。
同類だけど別の(fixされていない)バグなのでしょうか。
twitter - python dateutil unicode warning - Stack Overflow
http://stackoverflow.com/questions/21296475/python-dateutil-unicode-warning
日時・日付から文字列へ変換
ISO8601形式に変換する場合は、date.isoformat()メソッドを使います。
datetimeオブジェクトやdateオブジェクトを単純に文字列に変換する場合は、これが使われます。
任意のフォーマットで文字列に変換したい場合は、strftime()メソッドを使用します。
>>> from datetime import datetime, timezone, timedelta
>>>
>>> dt1 = datetime(2016, 7, 5, 13, 45) # naive
>>> dt2 = datetime(2016, 7, 5, 13, 45, tzinfo=timezone(timedelta(hours=+9))) # aware
>>> d = dt1.date()
>>> dt1, dt2, d
(datetime.datetime(2016, 7, 5, 13, 45), datetime.datetime(2016, 7, 5, 13, 45, tzinfo=datetime.timezone(datetime.timedelta(0, 32400))), datetime.date(2016, 7, 5))
>>>
>>> dt1.isoformat()
'2016-07-05T13:45:00'
>>> str(dt1)
'2016-07-05 13:45:00'
>>>
>>> dt2.isoformat()
'2016-07-05T13:45:00+09:00'
>>> str(dt2)
'2016-07-05 13:45:00+09:00'
>>>
>>> d.isoformat()
'2016-07-05'
>>> str(d)
'2016-07-05'
>>>
>>> dt1.strftime("%Y/%m/%d %H:%M:%S")
'2016/07/05 13:45:00'
>>> dt1.strftime("%Y/%m/%d %H:%M:%S %Z %z")
'2016/07/05 13:45:00 '
>>> dt2.strftime("%Y/%m/%d %H:%M:%S %Z %z")
'2016/07/05 13:45:00 UTC+09:00 +0900'
フォーマットの書式については、下記リファレンスを参照してください。
8.1.8. strftime() と strptime() の振る舞い - 8.1. datetime — 基本的な日付型および時間型 — Python 3.5.1 ドキュメント
http://docs.python.jp/3.5/library/datetime.html#strftime-strptime-behavior
2つの日時を比較する
比較演算子==,!=,<,<=,>,>=による比較が可能です。
datetimeとdateでは比較できません。
(TypeError: can't compare datetime.datetime to datetime.date)
また、datetime同士でもawareとnaive間では比較できません。
(TypeError: can't compare offset-naive and offset-aware datetimes)
どちらかの型にそろえてから比較する必要があります。
>>> from datetime import datetime, date
>>>
>>> dt1 = datetime(2016, 7, 1, 22, 30)
>>> dt2 = datetime(2016, 7, 5, 13, 45)
>>>
>>> dt1 == datetime(2016, 7, 1, 22, 30, 0)
True
>>> dt1 == dt1, dt1 == dt2, dt1 != dt1, dt1 != dt2, dt1 < dt2, dt1 > dt2, dt1 <= dt1, dt2 <= dt1, dt2 >= dt2, dt1 >= dt2
(True, False, False, True, True, False, True, False, True, False)
>>>
>>> d1 = dt1.date()
>>> d2 = dt2.date()
>>>
>>> d1 == date(2016, 7, 1)
True
>>> d1 == d1, d1 == d2, d1 != d1, d1 != d2, d1 < d2, d1 > d2, d1 <= d1, d2 <= d1, d2 >= d2, d1 >= d2
(True, False, False, True, True, False, True, False, True, False)
2つの日時の間隔を計算する
Pythonでは、日時の間隔、差分をtimedeltaオブジェクトで表現します。
(deltaは差分(difference⇒Δ)の意。)
timedeltaはdatetime同士またはdate同士の引き算(-演算)で得られます。
datetimeとdateでは計算できません。
(TypeError: unsupported operand type(s) for -)
また、datetime同士でもawareとnaive間では計算できません。
(TypeError: can't subtract offset-naive and offset-aware datetimes)
どちらかの型にそろえてから計算する必要があります。
>>> from datetime import datetime, date
>>>
>>> d1, d2 = date(2016, 7, 1), date(2016, 7, 3)
>>>
>>> type(d2 - d1)
<class 'datetime.timedelta'>
>>> d2 - d1
datetime.timedelta(2)
>>> str(d2 - d1)
'2 days, 0:00:00'
>>> str(d1 - d2)
'-2 days, 0:00:00'
>>>
>>> dt1, dt2 = datetime(2016, 7, 1, 10, 30), datetime(2016, 7, 3, 9, 10)
>>> dt2 - dt1
datetime.timedelta(1, 81600)
>>> str(dt2 - dt1)
'1 day, 22:40:00'
2つの日時の月数を計算する
前項で書いた通り、2つの日付の差分で返されるのは日数です。
2つの日付の間隔が「何か月間なのか」を知りたい場合はどうしたら良いでしょうか?
そういう場合は、dateutilモジュールのサブモジュールrelativedeltaを使ってみましょう。
基本的にはこれで解決できるはずです。
>>> from datetime import date
>>> from dateutil.relativedelta import relativedelta
>>>
>>> d1, d2 = date(2014, 11, 22), date(2016, 3, 1)
>>> str(d2 - d1)
'465 days, 0:00:00'
>>> delta = relativedelta(d2, d1)
>>> delta
relativedelta(years=+1, months=+3, days=+8)
>>> month_count = delta.years * 12 + delta.months
>>> month_count
15
12か月以上はyearsになってしまいますが、years * 12 + monthsで月数を算出することができました。
ここで少し気になるのが、月末がからんでくる計算、特にうるう年の2月前後の場合です。
そこで、2つの日付をそれぞれ1日ずつずらしていって、その場合のdeltaがどうなるかを確認してみました。
- 2つの日付を1日ずつずらして
relativedeltaの結果を調べるスクリプト
from datetime import date, timedelta
from dateutil.relativedelta import relativedelta
d1 = date(2016, 2, 26)
d2 = date(2016, 3, 26)
delta1day = timedelta(days=1)
for x in range(9):
print(d1, d2, relativedelta(d2, d1))
d1 += delta1day
d2 += delta1day
- 実行結果
2016-02-26 2016-03-26 relativedelta(months=+1)
2016-02-27 2016-03-27 relativedelta(months=+1)
2016-02-28 2016-03-28 relativedelta(months=+1)
2016-02-29 2016-03-29 relativedelta(months=+1)
2016-03-01 2016-03-30 relativedelta(days=+29)
2016-03-02 2016-03-31 relativedelta(days=+29)
2016-03-03 2016-04-01 relativedelta(days=+29)
2016-03-04 2016-04-02 relativedelta(days=+29)
2016-03-05 2016-04-03 relativedelta(days=+29)
さらに先の日付まで見てみましたが、大雑把にいうとどうやら2月の月末をまたぐ場合にだけ特別扱いをしているようです。
それ以外はずっと同じ日数(+29)になりました。
2つの日付の間隔を1日増やしてみると、今度は30日の月の月末をまたいでいる場合とそうでない場合で日数が変わりました。
きっと、月末日で補正をかけているのでしょう。
この辺の性質を理解しておけば大丈夫そうですね。
日付・日時の増減
datetime - datetimeやdate - dateがtimedeltaになることは既に書きましたが、
日付・日時の増減については、timedeltaを足し引きすることで、増減されたdatetimeやdateを得ることができます。
>>> from datetime import datetime, date, timedelta
>>>
>>> dt = datetime(2016, 7, 5, 13, 45)
>>> d = dt.date()
>>>
>>> dt + timedelta(days=5, minutes=168)
datetime.datetime(2016, 7, 10, 16, 33)
>>> d - timedelta(days=13)
datetime.date(2016, 6, 22)
月単位での加減は、月数計算のときと同じく、dateutilモジュールのサブモジュールrelativedeltaを使用します。
>>> from datetime import date
>>> from dateutil.relativedelta import relativedelta
>>>
>>> date(2016, 7, 5) - relativedelta(months=32)
datetime.date(2013, 11, 5)
naiveとawareの相互変換
以下の例は、Python3において、標準モジュールだけでnaiveとawareの相互変換を確認したものです。
Python2(正確にはPython3.2未満)にはtimezone型が存在しないので、代わりにpytzモジュールを使ってください。
naiveなdatetimeをawareなdatetimeにするには、datetime.replace()メソッドを使います。
>>> from datetime import datetime, timezone, timedelta
>>>
>>> jst = timezone(timedelta(hours=+9)) # pytzを使う場合は pytz.timezone('Asia/Tokyo')
>>> jst
datetime.timezone(datetime.timedelta(0, 32400))
>>> dt = datetime(2016, 7, 5, 13, 45) # naive
>>> dt
datetime.datetime(2016, 7, 5, 13, 45)
>>> dt2 = dt.replace(tzinfo=jst) # aware
>>> dt2
datetime.datetime(2016, 7, 5, 13, 45, tzinfo=datetime.timezone(datetime.timedelta(0, 32400)))
>>> str(dt2)
'2016-07-05 13:45:00+09:00'
参考資料#4-2によると、datetime.replace()メソッドでタイムゾーンを付加した場合に、少しおかしな挙動をするという報告がありました。
代替案として、jst.localize(datetime(...))を使う方法が示されています。
私の環境では再現しませんでしたので、pytzの古いバージョンでのバグなのかも知れません。
逆に、awareなdatetimeをnaiveなdatetimeにするには、同じくdatetime.replace()メソッドを使います。
タイムゾーンには、「無し」を意味するNoneを指定します。
# (上記の続き)
>>> dt3 = dt2.replace(tzinfo=None)
>>> dt3
datetime.datetime(2016, 7, 5, 13, 45)
>>> str(dt3)
'2016-07-05 13:45:00'
struct_timeをdatetimeまたはdateに変換
タイムスタンプ型をstruct_timeで表すことがありますが、これをdatetime型に変換したい場合。
time.mktime()関数とdatetime.fromtimestamp()関数を使って、
struct_time→timestamp(float)→datetime
の順に変換します。
>>> from datetime import datetime, date
>>> from time import localtime, mktime
>>>
>>> tm = localtime() # struct_time
>>> t = mktime(tm) # タイムスタンプ(float)に変換
>>> datetime.fromtimestamp(t)
datetime.datetime(2016, 7, 12, 22, 31, 15)
>>> date.fromtimestamp(t)
datetime.date(2016, 7, 12)
struct_timeがタプルであることを利用して、次のように書くこともできます。
# (上記の続き)
>>> datetime(*tm[:6])
datetime.datetime(2016, 7, 12, 22, 31, 15)
tm[:6]は年月日時分秒のタプルが得られますので、それをdatetimeのコンストラクターに6つの引数として渡しています。
これは簡潔に書けますが、可読性が低下するので避けたほうが良いかも知れません。
datetimeまたはdateをstruct_timeに変換
前項とは逆に、datetimeオブジェクトやdateオブジェクトをstruct_timeオブジェクトに変換したい場合は、
date.timetuple()メソッドを使うとstruct_timeが得られます。
>>> from datetime import datetime
>>>
>>> dt = datetime(2016, 7, 3, 12, 25)
>>> d = dt.date()
>>>
>>> dt.timetuple()
time.struct_time(tm_year=2016, tm_mon=7, tm_mday=3, tm_hour=12, tm_min=25, tm_sec=0, tm_wday=6, tm_yday=185, tm_isdst=-1)
>>> d.timetuple()
time.struct_time(tm_year=2016, tm_mon=7, tm_mday=3, tm_hour=0, tm_min=0, tm_sec=0, tm_wday=6, tm_yday=185, tm_isdst=-1)
日付・日時のリストを生成する
ここでは日付の例だけ書きます。
日時の場合でも、型と単位を変えればいずれの方法も同様に適用できるはずです。
有限の日付リストを生成するには、timedeltaとrangeを組み合わせて、内包表記でリストを作る方法がすぐに思いつきました。
>>> from datetime import date, timedelta
>>>
>>> start_date = date(2016, 7, 5)
>>> a = [start_date + timedelta(days=x) for x in range(5)]
>>> a
[datetime.date(2016, 7, 5), datetime.date(2016, 7, 6), datetime.date(2016, 7, 7), datetime.date(2016, 7, 8), datetime.date(2016, 7, 9)]
...が、これだと1行で書けないのが少し残念です。
(start_dateの代わりに直接date(2016, 7, 5)を書けばできますが、もちろんそれは無し。)
dateutilモジュールのrruleサブモジュールを使うと、1行で書けます。
>>> from datetime import date
>>> from dateutil.rrule import rrule, DAILY
>>>
>>> a = [x.date() for x in rrule(DAILY, count=5, dtstart=date(2016, 7, 5))]
>>> a
[datetime.date(2016, 7, 5), datetime.date(2016, 7, 6), datetime.date(2016, 7, 7), datetime.date(2016, 7, 8), datetime.date(2016, 7, 9)]
そうそう、こういう風に書きたかったんです。
場合によっては、Pandasモジュール(pandas.date_range)を使った方が便利かも知れません。
詳しくは参考資料#5を参照して下さい。
閏年(うるうどし)の判定
calendarモジュールのisleap関数を使います。
>>> import calendar
>>>
>>> calendar.isleap(2016)
True
>>> calendar.isleap(2015)
False
>>>
>>> from datetime import date
>>>
>>> d = date(2016, 7, 5)
>>> calendar.isleap(d.year)
True
datetimeモジュールに属するオブジェクトのbool評価
datetimeモジュール内の日時関連オブジェクトは、Python3.5の時点では、timedelta(0)と等価のものを除き、すべてTrueと評価されます。
(timezoneについては、ドキュメントに記載がありませんでしたので、「すべて」には含みません。)
>>> from datetime import *
>>>
>>> bool(datetime.fromtimestamp(0))
True
>>> bool(date.fromtimestamp(0))
True
>>> bool(time(0, 0, 0))
True
>>> bool(timedelta(1))
True
>>> bool(timedelta(0))
False
>>> bool(timezone.utc)
True
ところで、Python2では、午前零時ちょうどのtimeオブジェクトはFalseと評価されます。
>>> from datetime import *
>>> bool(time(0, 0, 0))
False
これは、Python2というよりも、Python3.5未満で存在したバグ(Issue13936)で、Python3.5で修正された挙動です。
Python3.4.3で確認したところ、やはりFalseとなりました。
処理時間計算
他の言語でも使われる方法ですが、(処理後のタイムスタンプ - 処理前のタイムスタンプ)で算出します。
import time
t = time.time()
time.sleep(3.1)
print(time.time() - t)
# => 3.0999999046325684
今回は扱いませんが、コード断片の実行時間を計測するには、下記のモジュールを利用する方法もあります。
27.5. timeit — 小さなコード断片の実行時間計測 — Python 3.5.1 ドキュメント
http://docs.python.jp/3.5/library/timeit.html
付録
直列化サンプル
各オブジェクトをpickleにより直列化したしたときのイメージです。
- Python2での実行結果
>>> from datetime import datetime
>>> import pickle
>>>
>>> dt = datetime(2016, 7, 5, 13, 45)
>>>
>>> pickle.dumps(dt) # datetime
"cdatetime\ndatetime\np0\n(S'\\x07\\xe0\\x07\\x05\\r-\\x00\\x00\\x00\\x00'\np1\ntp2\nRp3\n."
>>> pickle.dumps(dt.date()) # date
"cdatetime\ndate\np0\n(S'\\x07\\xe0\\x07\\x05'\np1\ntp2\nRp3\n."
>>> pickle.dumps(dt.timetuple()) # struct_time
'ctime\nstruct_time\np0\n((I2016\nI7\nI5\nI13\nI45\nI0\nI1\nI187\nI-1\ntp1\n(dp2\ntp3\nRp4\n.'
>>> pickle.dumps(dt - dt) # timedelta
'cdatetime\ntimedelta\np0\n(I0\nI0\nI0\ntp1\nRp2\n.'
- Python3での実行結果
>>> from datetime import datetime
>>> import pickle
>>>
>>> dt = datetime(2016, 7, 5, 13, 45)
>>> pickle.dumps(dt) # datetime
b'\x80\x03cdatetime\ndatetime\nq\x00C\n\x07\xe0\x07\x05\r-\x00\x00\x00\x00q\x01\x85q\x02Rq\x03.'
>>> pickle.dumps(dt.date()) # date
b'\x80\x03cdatetime\ndate\nq\x00C\x04\x07\xe0\x07\x05q\x01\x85q\x02Rq\x03.'
>>> pickle.dumps(dt.timetuple()) # struct_time
b'\x80\x03ctime\nstruct_time\nq\x00(M\xe0\x07K\x07K\x05K\rK-K\x00K\x01K\xbbJ\xff\xff\xff\xfftq\x01}q\x02(X\x07\x00\x00\x00tm_zoneq\x03NX\t\x00\x00\x00tm_gmtoffq\x04Nu\x86q\x05Rq\x06.'
>>> pickle.dumps(dt - dt) # timedelta
b'\x80\x03cdatetime\ntimedelta\nq\x00K\x00K\x00K\x00\x87q\x01Rq\x02.'
参考資料
#1.
(公式ドキュメント・標準ライブラリーリファレンス)
8.1. datetime — 基本的な日付型および時間型 — Python 3.5.1 ドキュメント
http://docs.python.jp/3.5/library/datetime.html#module-datetime
8.1. datetime — 基本的な日付型および時間型 — Python 2.7.x ドキュメント
http://docs.python.jp/2/library/datetime.html#module-datetime
(datetime以外のモジュールのリンクは冗長なので省きます。上記リンクのページのどこかにリンクがあるのでそこから飛んでください。)
#2.
dateutil - powerful extensions to datetime — dateutil 2.5.3 documentation
https://dateutil.readthedocs.io/en/stable/
#3.
pytz 2016.4 : Python Package Index
https://pypi.python.org/pypi/pytz/
#4-1.
Pythonの日付処理とTimeZone | Nekoya Press
http://nekoya.github.io/blog/2013/06/21/python-datetime/
#4-2.
Pythonでdatetimeにtzinfoを付与するのにreplaceを使ってはいけない | Nekoya Press
http://nekoya.github.io/blog/2013/07/05/python-datetime-with-jst/
#5.
Python pandas で日時関連のデータ操作をカンタンに - StatsFragments
http://sinhrks.hatenablog.com/entry/2014/11/09/183603