2017-07-21 Fri 05:10
逆引きPython
INDEX
日付・時刻
TimeZoneの罠
Pythonのdatetime.datetimeにはTimeZone関連のややこしい問題がある。
- コンストラクタにtzinfoを渡すと夏時間を正しく認識できない
- 時刻が確定する前にTimeZone情報を付与すると問題が起きる
- naiveなdatetimeオブジェクトにreplaceでtzinfoを付与すると、日本時間がJSTでなくCJTになる
詳細は以下のエントリを参照のこと。
現時刻を取得する
上記の問題を回避しつつawareなdatetimeオブジェクトを取得する。
def now(with_microsecond=False, tzinfo=None): """Better datetime.datetime.now() - avoid DST problem (datetime constructor) - avoid JST/CJT problem (replace naive datetime) Args:with_microsecond timezone object (optional, default UTC) Returns: aware datetime object """ dt = datetime.datetime.now(pytz.utc) if not with_microsecond: dt = dt.replace(microsecond=0) return dt.astimezone(tzinfo) if tzinfo else dt
UNIX timeを扱う
現時刻をUNIX timeとして取得する
>>> import calendar >>> import datetime >>> calendar.timegm(datetime.datetime.utcnow().timetuple()) 1388738304
- time.mktimeはlocaltimeを扱い、caldner.timegmはUTCを扱う
- calender.timegmの方が速い。
datetimeオブジェクトとUNIX timeの変換
awareなdatetimeオブジェクトdtをUNIX timeに変換する。
>>> import calendar >>> calendar.timegm(dt.astimezone(pytz.utc).timetuple()) 1388738381
UNIX timeをawareなdatetimeに変換する。
>>> import datetime >>> import pytz >>> datetime.datetime.fromtimestamp(1388738381, pytz.utc) datetime.datetime(2014, 1, 3, 8, 39, 41, tzinfo=)
上の例ではUTCだが、TimeZone情報を後から付与するので、夏時間のある地域でも問題ない。
月の末日を求める
>>> import calendar >>> calendar.monthrange(2014, 2)[1] 28
monthrange()が指定月の1日の曜日と、月の日数をtupleで返すので後者を取ればよい。