2015-01-23 15 views
11

Trong python 2, ta có:hành vi kỳ lạ của datetime tròn giữa python 2 & 3

>>> datetime.datetime.utcfromtimestamp(1000000000005.0/1000.0) 
datetime.datetime(2001, 9, 9, 1, 46, 40, 5000) 

Nhưng trong python 3, ta có:

>>> datetime.datetime.utcfromtimestamp(1000000000005.0/1000.0) 
datetime.datetime(2001, 9, 9, 1, 46, 40, 4999) 

nguyên nhân gây ra làm tròn kỳ lạ này là gì hành vi và nó được dự định? Không phải là 1000000000005.0 vẫn còn trong phạm vi của đôi với một vài chữ số để phụ tùng?

+0

Thú vị tìm thấy. Bạn có thể đăng hệ điều hành của bạn, python sys.version? – dmg

+0

@ dmg Tôi đã thử nghiệm điều này trên python 3.4.1, 3.4.2, linux & windows 7. – simonzack

+0

nó chắc chắn đã làm với cách làm tròn được thực hiện trong python3, nếu bạn sử dụng bất kỳ giá trị từ 5 xuống nó làm tròn xuống và lên cho các giá trị> 5 –

Trả lời

1

Dưới đây tôi về cơ bản bao gồm utcfromtimestamp (tôi đã sửa đổi nó một chút thành độc lập).

Trong Python 2:

import time, datetime 
def utcfromtimestamp(t): 
    y, m, d, hh, mm, ss, weekday, jday, dst = time.gmtime(t) 
    us = int((t % 1.0) * 1000000) 
    ss = min(ss, 59) 
    return datetime.datetime(y, m, d, hh, mm, ss, us) 

Trong Python 3:

import time, datetime 
def utcfromtimestamp(t): 
    t, frac = divmod(t, 1.0) 
    us = int(frac * 1e6) 
    if us == 1000000: 
     t += 1 
     us = 0 
    y, m, d, hh, mm, ss, weekday, jday, dst = time.gmtime(t) 
    ss = min(ss, 59) 
    return datetime.datetime(y, m, d, hh, mm, ss, us) 

(Đầu vào 1000000000005.0/1000.0 được tính toán để 1000000000.005.)

Trong phiên bản độc lập của tôi:

Python 2 sử dụng toán tử modulus % để xác định nếu đầu vào là một số nguyên hoặc một phần nhỏ. Tuyên bố (t % 1.0) * 1000000 sau đó nhân số lẻ (trong trường hợp của chúng tôi 0.004999995231628418) theo 1000000. Điều này trả về 4999.995231628418, được làm tròn xuống 4999 bởi int.

Python 3 sử dụng divmod để trả lại toàn bộ số (t) 1000000000.0 và phần (frac) 0.005. Thay vì trả lại số này, trả lại t1000000000frac0.004999995231628418. Sau đó, nó sẽ tính toán us sử dụng frac * 1e6. Đây là cách nhân số 0.004999995231628418 của bạn bằng 1000000 dẫn đến 4999.995231628418, được làm tròn xuống 4999 bởi int.

Không có sự khác biệt thực sự trong các phương pháp được sử dụng. Cả hai đều chính xác và trả về cùng một kết quả. Kết luận của tôi là Python 2 làm tròn micro giây lên, trong khi Python 3 làm tròn chúng xuống.