2015-08-07 19 views
9

delorean docs hiển thị theo cách này để có được thời gian hiện tại trong một múi giờ chousing datetime:khi nào `datetime.now (pytz_timezone)` không thành công?

from datetime import datetime 
from pytz import timezone 

EST = "US/Eastern" 
UTC = "UTC" 

d = datetime.utcnow() 
utc = timezone(UTC) 
est = timezone(EST) 
d = utc.localize(d) 
d = est.normalize(EST) 

và so sánh nó với mã delorian dựa trên:

from delorean import Delorean 

EST = "US/Eastern" 

d = Delorean(timezone=EST) 

I believe ví dụ datetime nên được viết như:

from datetime import datetime 
import pytz 

eastern_timezone = pytz.timezone("US/Eastern") 
d = datetime.now(eastern_timezone) 

ngắn gọn hơn.

Có trường hợp nào khi ví dụ mã cuối cùng bị lỗi trong khi ví dụ đầu tiên tiếp tục hoạt động không?


Cập nhật:the current example:

from datetime import datetime 
import pytz 

d = datetime.utcnow() 
d = pytz.utc.localize(d) 

est = pytz.timezone('US/Eastern') 
d = est.normalize(d) 
return d 

rằng vẫn còn quá rườm rà.

Các ảnh tĩnh câu hỏi đứng: do you need the explicit round-trip via utc and tz.normalize() or can you use datetime.now(tz) instead?

+0

Mục tiêu của ông là đưa ra một ví dụ trên trang chính của dự án về cách sử dụng một 'Delorean' là sạch hơn việc sử dụng' datetime' và 'pytz'. Đó là một ví dụ xấu vì đó là mã không chính xác và có thể được xử lý tốt hơn theo ví dụ của bạn, nhưng ví dụ của bạn không đáp ứng được mục tiêu ban đầu. Có thể đề xuất một ví dụ mới cho thấy một trường hợp 'localize' và' normalize' thực sự cần thiết và cách nó được xử lý dễ dàng hơn với 'Delorean'? – heenenee

+1

Tôi đã gửi [vấn đề] (https://github.com/myusuf3/delorean/issues/70) với delorean, vì vậy họ đã tạo [yêu cầu kéo] (https://github.com/myusuf3/delorean/pull/ 71/tệp) làm sạch ví dụ đầu tiên. (Họ cũng làm sạch các ví dụ delorean.) –

+0

@heenenee: câu hỏi của tôi là về 'datetime.now (tz)': cho dù bạn luôn có thể sử dụng nó để trả về thời gian hiện tại trong một múi giờ nhất định thay vì 'est.normalize (utc) .localize (datetime.uctnow()). astimezone (est)) '. – jfs

Trả lời

9

Khi nào datetime.now(pytz_timezone) thất bại?

Theo như tôi có thể biết, không có trường hợp nào có thể bị lỗi. datetime.now gọi hàm fromutc trên cá thể tzinfo được chuyển vào tham số. Tất cả chuyển đổi từ UTC đến giờ địa phương đều rõ ràng, do đó không có cơ hội cho sự thất bại.

Ngoài ra, mã ban đầu thậm chí không hoạt động.

d = est.normalize(EST) 

này sẽ xuất hiện để thông qua một chuỗi như là tham số chỉ để normalize, mà được thiết kế để có một datetime. Điều này cho phép:

AttributeError: 'str' object has no attribute 'tzinfo' 

Tôi tin rằng họ có nghĩa là để viết:

d = est.normalize(d.astimezone(est)) 

Điều đó nói rằng, tôi không nghĩ rằng tính cách rườm rà của mã của họ thêm nhiều giá trị. Như bạn đã nói, nó chỉ là dễ dàng để làm điều này trong một bước duy nhất:

d = datetime.now(est) 

Nhìn vào cpython source code for datetime.now, tôi có thể thấy rằng khi một đối tượng tzinfo được cung cấp, nó gọi phương thức fromutc trên đối tượng đó.

if (self != NULL && tz != Py_None) { 
    /* Convert UTC to tzinfo's zone. */ 
    PyObject *temp = self; 

    self = _PyObject_CallMethodId(tz, &PyId_fromutc, "O", self); 
    Py_DECREF(temp); 
} 

Sau đó, trong nguồn pytz, tôi thấy rằng phương pháp fromutc được thực hiện khác nhau tùy thuộc vào việc các khu vực là pytz.UTC, hoặc một thể hiện của StaticTzInfo, hoặc DstTzInfo. Trong cả ba trường hợp, việc chuyển đổi từ giá trị UTC đầu vào sang múi giờ đích là rõ ràng.Đây là việc thực hiện DstTzInfo, đó là phức tạp hơn của ba:

def fromutc(self, dt): 
    '''See datetime.tzinfo.fromutc''' 
    if (dt.tzinfo is not None 
     and getattr(dt.tzinfo, '_tzinfos', None) is not self._tzinfos): 
     raise ValueError('fromutc: dt.tzinfo is not self') 
    dt = dt.replace(tzinfo=None) 
    idx = max(0, bisect_right(self._utc_transition_times, dt) - 1) 
    inf = self._transition_info[idx] 
    return (dt + inf[0]).replace(tzinfo=self._tzinfos[inf]) 

này sẽ xuất hiện để tìm ra quá trình chuyển đổi từ _utc_transition_times của múi giờ, sau đó áp dụng nó vào trở datetime. Không có sự mơ hồ theo hướng này, do đó kết quả sẽ tương đương nhau.

Cũng đáng chú ý, trong the datetime docs nó nói rằng datetime.now tương đương với cách gọi:

tz.fromutc(datetime.utcnow().replace(tzinfo=tz)) 

Với nguồn fromutc trong pytz tôi đã giới thiệu trước đó, tôi không chắc chắn rằng đây là bất kỳ khác nhau hơn là chỉ:

tz.fromutc(datetime.utcnow()) 

Nhưng trong cả hai trường hợp, tôi không nghĩ rằng localizenormalize là cần thiết.

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