ฉันจะแยกสตริงเวลาที่มีมิลลิวินาทีในมันด้วยหลามได้อย่างไร


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 เพิ่มมาโคร strftime / strptime %fใหม่ซึ่งทำหน้าที่เป็นไมโครวินาที ไม่แน่ใจว่ามีการบันทึกไว้ที่ใดก็ตามหรือไม่ แต่ถ้าคุณใช้ 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 ซึ่งขยายจำนวน microseconds ในวัตถุ zero-padded ด้านซ้ายไปยังที่หก
ilkinulas

5
ฉันสามารถบอกได้ว่าเอกสาร Python จำเป็นต้องอัปเดต เอกสารสำหรับโมดูลเวลาที่%fไม่ได้พูดอะไรเกี่ยวกับ
phunehehe

14
Python docs ซึ่งเป็นรุ่น 2.7.3 นั้นมีความเข้าใจผิดเล็กน้อย สำหรับ strptime นั้น% f สามารถแสดงจำนวนทศนิยมได้ไม่เพียง 6 ตำแหน่งเท่านั้นเนื่องจากอาจมีหน่วยเป็นไมโครวินาที ดังนั้นโค้ดด้านบนจะแยกวิเคราะห์ 32.123 วินาทีและเก็บเป็น 123,000 ซึ่งเป็นสิ่งที่เราต้องการ
Michael Scheper

9
ตัวเลขใน%fนั้นถูกเติมด้วยศูนย์ทางด้านขวา (ไม่เหลือ!) ถึงทศนิยม 6 ตำแหน่ง 1 ได้รับการแจงถึง 100000, 12 ได้รับการแจงถึง 120000 และ 1234567 ผลิตValueError: unconverted data remains: 7
user443854

17
มันเป็นเพียงฉันหรือเป็นคำถามเกี่ยวกับมิลลิวินาทีไม่ใช่ microseconds?
Purrell

12

ฉันรู้ว่านี่เป็นคำถามที่เก่ากว่า แต่ฉันยังคงใช้ Python 2.4.3 และฉันต้องการค้นหาวิธีที่ดีกว่าในการแปลงสตริงข้อมูลเป็นวันที่และเวลา

วิธีแก้ปัญหาถ้า datetime ไม่รองรับ% f และไม่จำเป็นต้องลอง / ยกเว้นคือ:

    (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

สิ่งนี้ใช้กับ 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 จะถามเกี่ยวกับมิลลิวินาที แต่คำตอบสำหรับ microseconds น่าเสียดายที่ Python นั้นไม่ได้มีคำสั่งเป็นมิลลิวินาทีเพียงแค่ไมโครวินาที (ดูเอกสาร ) แต่คุณสามารถแก้ไขมันได้ด้วยการต่อท้ายสามศูนย์ในตอนท้ายของสตริงและแยกสตริงเป็นไมโครวินาทีเช่น:

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

ที่มีรูปแบบเช่นtime_str30/03/09 16:31:32.123

หวังว่านี่จะช่วยได้


2
ผมคิดว่าสิ่งเดียวกัน แต่แรก แต่ดูความคิดเห็นเกี่ยวกับคำตอบและเอกสาร มันเป็นไมโครวินาทีที่ไม่มีการบุรองดังนั้นจึง.123ตีความได้อย่างถูกต้องว่าเป็น 123,000 ไมโครวินาที
aschmied

1

ความคิดแรกของฉันคือลองผ่านมันเป็น '30/03/09 16: 31: 32.123' (มีจุดแทนเครื่องหมายโคลอนระหว่างวินาทีและมิลลิวินาที) แต่นั่นไม่ได้ผล ภาพรวมอย่างรวดเร็วที่เอกสารระบุว่ามีเศษเสี้ยววินาทีในทุกกรณี ...

อารุ่นที่แตกต่าง นี้ได้รับรายงานว่าเป็นข้อผิดพลาดและตอนนี้ใน 2.6+ คุณสามารถใช้ "% S% F" ที่จะแยกมัน


ไม่ได้ผล; เวลาเวลาเพียงไม่ทำมิลลิวินาที
DNS

1

จากรายการส่งเมลของ Python: การแยกวิเคราะห์เธรดมิลลิวินาทีแยกด้ายมิลลิวินาทีมีฟังก์ชั่นโพสต์อยู่ที่นั่นซึ่งดูเหมือนว่าจะทำให้งานเสร็จแม้ว่าตามที่ระบุไว้ในความคิดเห็นของผู้เขียนมันเป็นแฮ็ค มันใช้นิพจน์ทั่วไปเพื่อจัดการข้อยกเว้นที่เพิ่มขึ้นจากนั้นทำการคำนวณบางอย่าง

คุณสามารถลองทำนิพจน์และการคำนวณปกติก่อนส่งผ่านไปยัง strptime


ใช่ฉันรู้ว่าด้าย แต่ฉันกำลังมองหาวิธีที่ง่ายกว่า มีโมดูลใน lib python มาตรฐานที่ทำให้เวลาในการแยกวิเคราะห์ด้วยมิลลิวินาทีหรือไม่
ilkinulas

1

สำหรับ python 2 ฉันทำสิ่งนี้

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

มันพิมพ์เวลา "% H:% M:% S" แยก time.time () ไปยังสองสตริงย่อย (ก่อนและหลัง) xxxxxxx.xx และเนื่องจาก. xxx เป็นมิลลิวินาทีของฉันฉันเพิ่มซับสตริงที่สองลงใน "% ของฉัน 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.