ミリ秒を含む時間文字列をPythonでどのように解析できますか?


204

time.strptimeで日付/時刻を含む文字列を解析できます

>>> import time
>>> time.strptime('30/03/09 16:31:32', '%d/%m/%y %H:%M:%S')
(2009, 3, 30, 16, 31, 32, 0, 89, -1)

ミリ秒を含む時間文字列を解析するにはどうすればよいですか?

>>> time.strptime('30/03/09 16:31:32.123', '%d/%m/%y %H:%M:%S')
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/usr/lib/python2.5/_strptime.py", line 333, in strptime
    data_string[found.end():])
ValueError: unconverted data remains: .123

回答:


318

Python 2.6では、%fマイクロ秒を実行する新しいstrftime / strptimeマクロが追加されました。これがどこかで文書化されているかどうかはわかりません。しかし、2.6または3.0を使用している場合は、これを行うことができます。

time.strptime('30/03/09 16:31:32.123', '%d/%m/%y %H:%M:%S.%f')

編集:私は実際にtimeモジュールを操作したことがないので、最初はこれに気づきませんでしたが、time.struct_timeは実際にはミリ秒/マイクロ秒を格納していないようです。次のdatetimeようにを使用したほうがよい場合があります。

>>> from datetime import datetime
>>> a = datetime.strptime('30/03/09 16:31:32.123', '%d/%m/%y %H:%M:%S.%f')
>>> a.microsecond
123000

4
おかげでdocs.python.org/library/datetime.html:バージョン2.6の新機能:時間オブジェクトと日付時間オブジェクトは、オブジェクトのマイクロ秒数に展開される%f形式のコードをサポートし、左側にゼロが埋め込まれて6桁になります。
ilkinulas 2009年

5
Pythonドキュメントを更新する必要があることを伝えることができます。timeモジュールのドキュメントでは、について何も言われていません%f
phunehehe

14
Pythonドキュメントは、バージョン2.7.3の時点で、少し誤解を招く可能性があります。strptimeの場合、%fは実際には、マイクロ秒で予想される6だけでなく、小数点以下の任意の数を表すことができます。したがって、上記のコードは32.123秒を解析し、123,000µsとして保存します。これが目的です。
Michael Scheper 2013年

9
の数字は、小数点以下6桁まで右側に(左側ではなく)%fゼロが埋め込まれます。1は100000に解析され、12は120000に解析され、1234567が生成されますValueError: unconverted data remains: 7
user443854

17
それは私だけですか、それともミリ秒ではなくミリ秒についての質問でしたか?
Purrell、2015年

12

私はこれが古い質問であることを知っていますが、まだPython 2.4.3を使用しており、データの文字列を日時に変換するより良い方法を見つける必要がありました。

datetimeが%fをサポートせず、try / exceptを必要としない場合の解決策は次のとおりです。

    (dt, mSecs) = row[5].strip().split(".") 
    dt = datetime.datetime(*time.strptime(dt, "%Y-%m-%d %H:%M:%S")[0:6])
    mSeconds = datetime.timedelta(microseconds = int(mSecs))
    fullDateTime = dt + mSeconds 

これは、入力文字列「2010-10-06 09:42:52.266000」に対して機能します


1
dt.replace(microsecond=int(mSecs))
haridsv 2012

これはPython 2.5以前に適用されます。Python 2.6はstrptime '%f'をサポート
smci

4

nstehrの答えが参照するコードを(ソースから)与えるには:

def timeparse(t, format):
    """Parse a time string that might contain fractions of a second.

    Fractional seconds are supported using a fragile, miserable hack.
    Given a time string like '02:03:04.234234' and a format string of
    '%H:%M:%S', time.strptime() will raise a ValueError with this
    message: 'unconverted data remains: .234234'.  If %S is in the
    format string and the ValueError matches as above, a datetime
    object will be created from the part that matches and the
    microseconds in the time string.
    """
    try:
        return datetime.datetime(*time.strptime(t, format)[0:6]).time()
    except ValueError, msg:
        if "%S" in format:
            msg = str(msg)
            mat = re.match(r"unconverted data remains:"
                           " \.([0-9]{1,6})$", msg)
            if mat is not None:
                # fractional seconds are present - this is the style
                # used by datetime's isoformat() method
                frac = "." + mat.group(1)
                t = t[:-len(frac)]
                t = datetime.datetime(*time.strptime(t, format)[0:6])
                microsecond = int(float(frac)*1e6)
                return t.replace(microsecond=microsecond)
            else:
                mat = re.match(r"unconverted data remains:"
                               " \,([0-9]{3,3})$", msg)
                if mat is not None:
                    # fractional seconds are present - this is the style
                    # used by the logging module
                    frac = "." + mat.group(1)
                    t = t[:-len(frac)]
                    t = datetime.datetime(*time.strptime(t, format)[0:6])
                    microsecond = int(float(frac)*1e6)
                    return t.replace(microsecond=microsecond)

        raise

2

上記のDNS回答は実際には正しくありません。SOは約ミリ秒を要求していますが、答えはマイクロ秒です。残念ながら、Python`sにはミリ秒のディレクティブがなく、マイクロ秒しかありません(docを参照)。ただし、次のように、文字列の最後に3つのゼロを追加し、文字列をマイクロ秒として解析することで回避できます。

datetime.strptime(time_str + '000', '%d/%m/%y %H:%M:%S.%f')

どこtime_strのようにフォーマットされます30/03/09 16:31:32.123

お役に立てれば。


2
最初は同じことを思いましたが、回答とドキュメントのコメントを参照してください。これは左ゼロが埋め込まれたマイクロ秒なので.123、123,000マイクロ秒として正しく解釈されます
aschmied

1

私の最初の考えは、「30/03/09 16:31:32.123」(秒とミリ秒の間にコロンの代わりにピリオドを付けて)を渡してみることでした。しかし、それはうまくいきませんでした。ドキュメントを一目見ただけで、小数秒は無視されます...

ああ、バージョンの違い。これはバグとして報告され、 2.6以降では「%S.%f」を使用して解析できます。


それは機能しません。time.strptimeはミリ秒を実行しません。
DNS

1

Pythonメーリングリストから:ミリ秒スレッドの解析。著者のコメントで述べられているように、それは一種のハックですが、仕事を成し遂げたように思われる関数がそこに投稿されています。正規表現を使用して、発生した例外を処理し、いくつかの計算を行います。

strptimeに渡す前に、正規表現と計算を事前に実行することもできます。


はい、私はそのスレッドを知っています。しかし、私はもっと簡単な方法を探しています。ミリ秒で時間を解析するモジュールを標準のpython libにありますか?
ilkinulas 2009年

1

Python 2の場合、私はこれをしました

print ( time.strftime("%H:%M:%S", time.localtime(time.time())) + "." + str(time.time()).split(".",1)[1])

時間 "%H:%M:%S"を出力し、time.time()を2つのサブストリング(。の前後に)に分割します。xxxxxxx.xxと.xxはミリ秒なので、2番目のサブストリングを "%"に追加しますH:%M:%S」

それが理にかなっていると思います:)出力例:

13:31:21.72点滅01


13:31:21.81点滅の終わり01


13:31:26.3ブリンク01


13:31:26.39点滅の終わり01


13:31:34.65レーン01の開始


弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.