2012-11-06 54 views
25

Tôi đang cố gắng viết một cặp hàm, dtut, chuyển đổi qua lại giữa thời gian unix bình thường (giây kể từ 1970-01-01 00:00:00 UTC) và một đối tượng datetime Python.Chuyển đổi một unixtime thành đối tượng datetime và ngược lại (cặp hàm chuyển đổi thời gian là nghịch đảo)

Nếu dtut là ngược thích hợp sau đó mã này sẽ in dấu thời gian tương tự hai lần:

import time, datetime 

# Convert a unix time u to a datetime object d, and vice versa 
def dt(u): return datetime.datetime.fromtimestamp(u) 
def ut(d): return time.mktime(d.timetuple()) 

u = 1004260000 
print u, "-->", ut(dt(u)) 

Than ôi, dấu thời gian thứ hai là 3600 giây (một giờ) ít hơn so với lần đầu tiên. Tôi nghĩ rằng điều này chỉ xảy ra cho những thời gian nhất định, có thể trong giờ đó mà thời gian tiết kiệm ánh sáng ban ngày bỏ qua. Nhưng có cách nào để viết dtut để chúng là những nghịch đảo thực sự của nhau không?

câu hỏi liên quan: Making matplotlib's date2num and num2date perfect inverses

+0

btw, nếu chức năng không làm gì nhưng gọi một chức năng với cùng các đối số thì bạn chỉ có thể gán nó: 'dt = datetime.datetime.utcfromtimestamp'. Các hàm là các công dân hạng nhất trong Python: bạn có thể chuyển chúng thành các tham số cho các hàm khác, trả về từ các hàm, v.v. – jfs

+0

Ah, đẹp, điểm tuyệt vời! Liệu nó có hiệu quả hơn để làm như vậy hay chỉ là vấn đề gọn gàng? Điều gì về 'def f (x): return foo (x)' vs 'f = lambda x: foo (x)'? (Nhớ lại của tôi là những cái tương đương, cả về mặt chức năng và hiệu quả.) – dreeves

+0

'f = g' có nghĩa là f, g là hai tên tham chiếu đến cùng một hàm. 'def' và' lambda' tạo hàm mới. – jfs

Trả lời

37

Bạn đang đúng khi cho rằng hành vi này có liên quan đến thời gian tiết kiệm ánh sáng ban ngày. Cách dễ nhất để tránh điều này là đảm bảo bạn sử dụng múi giờ không có tiết kiệm ánh sáng ban ngày, UTC có ý nghĩa nhất ở đây.

datetime.datetime.utcfromtimestamp()calendar.timegm() đối phó với thời gian UTC và hoàn toàn chính xác.

import calendar, datetime 

# Convert a unix time u to a datetime object d, and vice versa 
def dt(u): return datetime.datetime.utcfromtimestamp(u) 
def ut(d): return calendar.timegm(d.timetuple()) 

Đây là một chút giải thích đằng sau lý do tại sao datetime.datetime.fromtimestamp() có một vấn đề với thời gian tiết kiệm ánh sáng ban ngày, từ các tài liệu:

Return ngày và thời gian tương ứng với timestamp POSIX địa phương, như là trả lại bởi time.time(). Nếu tham số tùy chọn tz là None hoặc không được chỉ định, dấu thời gian được chuyển đổi thành ngày địa phương của nền tảng và thời gian và đối tượng ngày giờ trả về là ngây thơ.

Điều quan trọng ở đây là bạn có được đối tượng ngây thơ datetime.datetime, điều này có nghĩa là không có thông tin múi giờ (hoặc tiết kiệm ánh sáng ban ngày) như một phần của đối tượng. Điều này có nghĩa rằng nhiều timestamps biệt có thể ánh xạ tới cùng một đối tượng datetime.datetime khi sử dụng fromtimestamp(), nếu bạn tình cờ nhặt lần rơi trong tiết kiệm ánh sáng ban ngày thời gian cuộn lại:

>>> datetime.datetime.fromtimestamp(1004260000) 
datetime.datetime(2001, 10, 28, 1, 6, 40) 
>>> datetime.datetime.fromtimestamp(1004256400) 
datetime.datetime(2001, 10, 28, 1, 6, 40) 
+0

Hoàn hảo; cảm ơn! (Và tôi đã xác nhận rằng nó hoạt động cho tôi.) – dreeves

+0

['ut = lambda naive_utc_dt: (naive_utc_dt - datetime (1970,1,1)) .total_seconds()'] (http://stackoverflow.com/a/ 8778548/4279) – jfs

+0

@JFSebastian, muốn thêm câu trả lời đó làm câu trả lời? Có vẻ như bạn đã đúng (mặc dù tôi chưa xác minh phiên bản của bạn) và bạn phải là câu trả lời được chấp nhận ở đây. Tôi ghét dẫn đến sự lạc lối áp phích, chỉ với một liên kết trong các ý kiến ​​chỉ ra một cách tốt hơn! – dreeves

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