2014-10-02 11 views
9

Tôi muốn chuyển đổi định dạng ngày chuỗi để đánh dấu thời gian với micro tôi cố gắng kết quả mong đợi sau nhưng không đưa ra:Python: Chuyển đổi chuỗi để đánh dấu thời gian với micro

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

đâu các mili giây đi đâu?

+0

ngày nhập (2014-08-01) không tương ứng với dấu thời gian (2014-09-15 02: 30: 01.117Z) – jfs

Trả lời

12

Không có khe cắm cho thành phần micro trong một tuple thời gian:

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

Bạn sẽ có thêm những bằng tay:

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

Phương pháp khác mà bạn có thể làm theo là để tạo ra một timedelta() object liên quan đến kỷ nguyên, sau đó nhận dấu thời gian với timedelta.total_seconds() method:

epoch = datetime.datetime.fromtimestamp(0) 
(dt - epoch).total_seconds() 

Việc sử dụng thời gian địa phương epoch là khá thận trọng vì bạn có giá trị ngày giờ (không biết múi giờ) ngây thơ. Phương pháp này có thể không chính xác dựa trên lịch sử múi giờ địa phương của bạn, tuy nhiên, hãy xem J.F. Sebastian's comment. Bạn sẽ phải chuyển đổi giá trị datetime ngây thơ thành giá trị datetime nhận biết múi giờ đầu tiên bằng múi giờ địa phương của bạn trước khi trừ đi một kỷ nguyên thời gian nhận biết.

Vì vậy, việc tiếp cận phương pháp timetuple() + micro giây dễ dàng hơn.

Demo:

>>> dt = datetime.datetime.strptime(myDate, "%Y-%m-%d %H:%M:%S,%f") 
>>> epoch = datetime.datetime.fromtimestamp(0) 
>>> (dt - epoch).total_seconds() 
1406864512.117 
+0

** 1 ** '(dt - epoch)' không chính xác nếu ' dt' là thời gian địa phương ngây thơ. Thời gian địa phương có thể được thiết lập lại (chuyển tiếp DST vào mùa thu ở bán cầu bắc). Dấu thời gian sẽ ** không ** được đặt lại trong trường hợp này. ** 2 ** Đồng thời "thời gian địa phương" có thể gây hiểu nhầm. Kỷ nguyên là một cá thể * duy nhất * (1970 cho Python) - nó giống nhau trên toàn thế giới. Nếu thư viện C hỗ trợ cơ sở dữ liệu múi giờ lịch sử hoặc UTC cho múi giờ địa phương có cùng giá trị tại thời điểm đó thì 'datetime.fromtimestamp (0)' trả về thời gian cục bộ tương ứng với kỷ nguyên. – jfs

+0

@ J.F.Sebastian: giá trị 'epoch' sử dụng' fromtimestamp() ', không phải' utcfromtimestamp() ', để xử lý chênh lệch DST, chính xác vì giá trị' dt' là ngây thơ. –

+0

@ J.F.Sebastian: Tôi đã sử dụng 'utcfromtimestamp()' thay vào đó, trước tiên tôi phải làm cho 'dt' nhận biết múi giờ và do đó cho phép Python bù đắp cho các vấn đề DST. –

2

đâu các mili giây đi đâu?

Đây là phần dễ dàng. Cuộc gọi .timetuple() sẽ giảm bớt chúng. Bạn có thể thêm lại chúng bằng cách sử dụng thuộc tính .microsecond. Các datetime.timestamp() method from the standard library hoạt động theo cách mà các đối tượng datetime ngây thơ:

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

Nó là đủ nếu có thể ~ 1 lỗi giờ có thể được bỏ qua trong trường hợp của bạn. Tôi giả sử rằng bạn muốn micro giây và do đó bạn không thể bỏ qua ~ 1 giờ lỗi thời gian âm thầm.

Để chuyển đổi giờ địa phương được cung cấp dưới dạng chuỗi thành dấu thời gian POSIX chính xác là một nhiệm vụ phức tạp nói chung. Bạn có thể chuyển đổi giờ địa phương thành UTC và sau đó là get the timestamp from UTC time.

Có hai vấn đề chính:

  • giờ địa phương có thể không tồn tại hoặc ví dụ mơ hồtrong DST chuyển tiếp đồng thời có thể xảy ra hai lần
  • UTC bù đắp cho các múi giờ địa phương có thể khác nhau trong quá khứ và do đó một ngây thơ: local time minus epoch in local time formula may fail

Cả hai có thể được giải quyết bằng cách sử dụng cơ sở dữ liệu tz (pytz mô-đun bằng Python) :

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) 

kết quả là timestamp - một đối tượng timedelta, bạn có thể chuyển nó sang giây, mili giây, vv

sys cũng khác nhau tem có thể hoạt động khác nhau xung quanh/trong giây nhảy vọt. Hầu hết các ứng dụng có thể bỏ qua chúng tồn tại.

Nói chung, có thể đơn giản hơn để lưu dấu thời gian POSIX ngoài vào giờ địa phương thay vì cố gắng đoán từ giờ địa phương.

+0

Lưu ý: 'datetime.timestamp' chỉ có sẵn trong Python 3; OP đang sử dụng Python 2 (đánh giá bằng các câu lệnh 'print'). –

+0

@MartijnPieters: Tôi có * not * được đề xuất sử dụng phương thức '.timestamp()'. Tôi chỉ sử dụng nó như là một ví dụ (thiếu sót) thực hiện. – jfs

+0

Tôi không có ý định đề nghị bạn đã làm. Tôi chỉ chỉ ra rằng phương thức không tồn tại trong Python 2. –

1

Trong Python 3.4 và sau đó bạn có thể sử dụng

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

này không yêu cầu nhập khẩu các mô-đun time. Nó cũng sử dụng ít bước hơn nên nó sẽ nhanh hơn. Đối với các phiên bản cũ của python các câu trả lời được cung cấp khác có lẽ là lựa chọn tốt nhất của bạn.

Các vấn đề liên quan