Làm thế nào tôi có thể phân tích chuỗi thời gian chứa mili giây trong đó với python?


204

Tôi có thể phân tích các chuỗi chứa ngày / thời gian với 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)

Làm cách nào tôi có thể phân tích chuỗi thời gian chứa mili giây?

>>> 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

Câu trả lời:


318

Python 2.6 đã thêm một macro strftime / strptime mới %f, tính theo micro giây. Không chắc chắn nếu điều này được ghi nhận ở bất cứ đâu. Nhưng nếu bạn đang sử dụng 2.6 hoặc 3.0, bạn có thể làm điều này:

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

Chỉnh sửa: Tôi không bao giờ thực sự làm việc với timemô-đun, vì vậy tôi đã không nhận thấy điều này lúc đầu, nhưng nó xuất hiện vào thời điểm đó.struct_time không thực sự lưu trữ mili giây / micro giây. Bạn có thể tốt hơn khi sử dụng datetime, như thế này:

>>> 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
Cảm ơn docs.python.org/l Library / datetime.html: Mới trong phiên bản 2.6: các đối tượng thời gian và thời gian hỗ trợ mã định dạng% f mở rộng đến số micrô giây trong đối tượng, không đệm ở bên trái đến sáu vị trí.
ilkinote

5
Tôi có thể nói các tài liệu Python cần cập nhật. Tài liệu cho mô-đun thời gian không nói gì về %f.
phunehehe

14
Các tài liệu Python, kể từ phiên bản 2.7.3, có một chút sai lệch. Đối với thời gian ngắn,% f thực sự có thể đại diện cho bất kỳ số vị trí thập phân nào, không chỉ 6, như người ta có thể mong đợi trong vài giây. Vì vậy, đoạn mã trên sẽ phân tích 32.123 giây và lưu trữ dưới dạng 123.000 lượt, đó là những gì chúng ta muốn.
Michael Scheper

9
Số trong %fđược đệm bằng số không ở bên phải (không phải bên trái!) Đến 6 chữ số thập phân. 1 được phân tích thành 100000, 12 được phân tích thành 120000 và 1234567 tạo raValueError: unconverted data remains: 7
user443854

17
Có phải chỉ tôi hay là câu hỏi về mili giây, không phải micro giây?
Purrell 10/03/2015

12

Tôi biết đây là một câu hỏi cũ hơn nhưng tôi vẫn đang sử dụng Python 2.4.3 và tôi cần tìm một cách tốt hơn để chuyển đổi chuỗi dữ liệu thành datetime.

Giải pháp nếu datetime không hỗ trợ% f và không cần thử / ngoại trừ là:

    (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 

Điều này hoạt động cho chuỗi đầu vào "2010-10-06 09: 42: 52.266000"


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

Điều này áp dụng cho Python 2.5 trở về trước. Python 2.6 hỗ trợ strptime '% f'
smci

4

Để cung cấp mã mà câu trả lời của nstehr đề cập đến (từ nguồn của nó ):

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

Câu trả lời DNS ở trên thực sự không chính xác. SO đang hỏi về mili giây nhưng câu trả lời là cho micro giây. Thật không may, Python `không có lệnh trong một phần nghìn giây, chỉ là micro giây (xem tài liệu ), nhưng bạn có thể giải quyết nó bằng cách nối thêm ba số không ở cuối chuỗi và phân tích chuỗi dưới dạng micro giây, như:

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

nơi time_strđược định dạng như thế nào 30/03/09 16:31:32.123.

Hi vọng điêu nay co ich.


2
Tôi đã nghĩ điều tương tự ban đầu, nhưng xem các bình luận về câu trả lời và các tài liệu . Đó là micrô giây không đệm , do đó .123được hiểu chính xác là 123.000 micro giây
xác định vào

1

Suy nghĩ đầu tiên của tôi là thử vượt qua '30 / 03/09 16: 31: 32.123 '(với một khoảng thời gian thay vì dấu hai chấm giữa giây và mili giây.) Nhưng điều đó không hiệu quả. Nhìn lướt qua các tài liệu cho thấy rằng các giây phân số bị bỏ qua trong mọi trường hợp ...

Ah, phiên bản khác biệt. Điều này đã được báo cáo là một lỗi và bây giờ trong 2.6+, bạn có thể sử dụng "% S.% f" để phân tích cú pháp.


Điều đó không hiệu quả; time.strptime chỉ không làm mili giây.
DNS

1

từ danh sách gửi thư python: phân tích luồng mili giây . Có một chức năng được đăng ở đó dường như để hoàn thành công việc, mặc dù như được đề cập trong các bình luận của tác giả, đó là một loại hack. Nó sử dụng các biểu thức chính quy để xử lý ngoại lệ được nêu ra, và sau đó thực hiện một số tính toán.

Bạn cũng có thể thử thực hiện các biểu thức thông thường và tính toán trước, trước khi chuyển nó sang thời gian.


vâng, tôi biết chủ đề đó. Nhưng tôi đang tìm kiếm một cách đơn giản hơn. Có mô-đun nào trong lib python nổi bật làm cho thời gian phân tích cú pháp với mili giây không?
ilkinote

1

Đối với python 2 tôi đã làm điều này

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

nó in thời gian "% H:% M:% S", chia thời gian.time () thành hai chuỗi con (trước và sau.) xxxxxxx.xx và vì .xx là mili giây của tôi nên tôi thêm chuỗi con thứ hai vào "% H:% M:% S "

hy vọng điều đó có ý nghĩa :) Ví dụ đầu ra:

13: 31: 21.72 Nháy mắt 01


13: 31: 21.81 KẾT THÚC 01


13: 31: 26.3 Nháy mắt 01


13: 31: 26,39 KẾT THÚC 01


13: 31: 34,65 Bắt đầu từ ngõ 01


Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.