web-dev-qa-db-ja.com

Python:文字列をマイクロ秒のタイムスタンプに変換する

文字列の日付形式をマイクロ秒のタイムスタンプに変換したいのですが、次のことを試してみますが、期待した結果が得られません。

"""input string date -> 2014-08-01 04:41:52,117
expected result -> 1410748201.117"""

import time
import datetime

myDate = "2014-08-01 04:41:52,117"
timestamp = time.mktime(datetime.datetime.strptime(myDate, "%Y-%m-%d %H:%M:%S,%f").timetuple())

print timestamp
> 1410748201.0

ミリ秒はどこに行きましたか?

11
Krilin

時間タプルにはマイクロ秒コンポーネントのスロットがありません:

_>>> import time
>>> import datetime
>>> myDate = "2014-08-01 04:41:52,117"
>>> datetime.datetime.strptime(myDate, "%Y-%m-%d %H:%M:%S,%f").timetuple()
time.struct_time(tm_year=2014, tm_mon=8, tm_mday=1, tm_hour=4, tm_min=41, tm_sec=52, tm_wday=4, tm_yday=213, tm_isdst=-1)
_

それらを手動で追加する必要があります:

_>>> dt = datetime.datetime.strptime(myDate, "%Y-%m-%d %H:%M:%S,%f")
>>> time.mktime(dt.timetuple()) + (dt.microsecond / 1000000.0)
1406864512.117
_

あなたが従うことができる他の方法は、エポックに関連する timedelta() object を生成し、次に timedelta.total_seconds() method でタイムスタンプを取得することです=:

_Epoch = datetime.datetime.fromtimestamp(0)
(dt - Epoch).total_seconds()
_

現地時間のエポックの使用は、ナイーブな(タイムゾーンに対応していない)日時値があるため、かなり慎重です。この方法canはローカルタイムゾーンの履歴に基づいて不正確ですが、 J.F。Sebastianのコメント を参照してください。タイムゾーン対応のエポックを差し引く前に、まずローカルタイムゾーンを使用して、ナイーブな日時値をタイムゾーン対応の日時値に変換する必要があります。

そのため、timetuple() +マイクロ秒のアプローチに固執する方が簡単です。

デモ:

_>>> dt = datetime.datetime.strptime(myDate, "%Y-%m-%d %H:%M:%S,%f")
>>> Epoch = datetime.datetime.fromtimestamp(0)
>>> (dt - Epoch).total_seconds()
1406864512.117
_
13
Martijn Pieters

Python 3.4以降では、

timestamp = datetime.datetime.strptime(myDate, "%Y-%m-%d %H:%M:%S,%f").timestamp()

これには、timeモジュールをインポートする必要はありません。また、使用するステップが少ないため、より高速になります。 pythonの古いバージョンの場合、他に提供されている回答がおそらく最良の選択肢です。

ただし、結果のタイムスタンプはmyDateをUTCではなく現地時間で解釈するため、myDateがUTCで指定された場合に問題が発生する可能性があります。

3
user144153

ミリ秒はどこに行きましたか?

簡単な部分です。 .timetuple()呼び出しはそれらを削除します。 _.microsecond_属性を使用してそれらを再び追加できます。標準ライブラリの datetime.timestamp()メソッド は、単純なdatetimeオブジェクトに対してそのように機能します。

_def timestamp(self):
    "Return POSIX timestamp as float"
    if self._tzinfo is None:
        return _time.mktime((self.year, self.month, self.day,
                             self.hour, self.minute, self.second,
                             -1, -1, -1)) + self.microsecond / 1e6
    else:
        return (self - _Epoch).total_seconds()
_

可能であれば、1時間程度のエラーは無視してかまいません。私はあなたがマイクロ秒を望んでいると思います、それゆえあなたは黙って1時間の時間エラーを無視することはできません.

文字列として指定された現地時間をPOSIXタイムスタンプに正しく変換することは、一般的に複雑な作業です。現地時間をUTCに変換してから、 TC時間からタイムスタンプを取得 できます。

主な問題は2つあります。

どちらもtzデータベース(Pythonではpytzモジュール)を使用して解決できます。

_from datetime import datetime
import pytz # $ pip install pytz
from tzlocal import get_localzone # $ pip install tzlocal

tz = get_localzone() # get pytz timezone corresponding to the local timezone

naive_d = datetime.strptime(myDate, "%Y-%m-%d %H:%M:%S,%f")
# a) raise exception for non-existent or ambiguous times
d = tz.localize(naive_d, is_dst=None)
## b) assume standard time, adjust non-existent times
#d = tz.normalize(tz.localize(naive_d, is_dst=False))
## c) assume DST is in effect, adjust non-existent times
#d = tz.normalize(tz.localize(naive_d, is_dst=True))
timestamp = d - datetime(1970, 1, 1, tzinfo=pytz.utc)
_

結果はtimestamp-timedeltaオブジェクトです。秒、ミリ秒などに変換できます。

また、うるう秒の前後では、システムによって動作が異なる場合があります。ほとんどのアプリケーションはそれらが存在することを無視できます。

一般的に、POSIXタイムスタンプに加えて現地時間から推測するのではなく、現地時間に格納する方が簡単な場合があります。

2
jfs