Nekoya Press

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情報を後から付与するので、夏時間のある地域でも問題ない。

    月の末日を求める

    calendar.monthrange()を使う。

    >>> import calendar
    >>> calendar.monthrange(2014, 2)[1]
    28
    

    monthrange()が指定月の1日の曜日と、月の日数をtupleで返すので後者を取ればよい。

    nekoya.github.io