2009-08-31 21 views
26

Cách nào đúng để chuyển đổi thời gian ngây thơ và tzinfo thành thời gian UTC? Nói rằng tôi có:pytz utc conversion

d = datetime(2009, 8, 31, 22, 30, 30) 
tz = timezone('US/Pacific') 

cách Đầu tiên, pytz lấy cảm hứng:

d_tz = tz.normalize(tz.localize(d)) 
utc = pytz.timezone('UTC') 
d_utc = d_tz.astimezone(utc) 

cách Thứ hai, từ UTCDateTimeField

def utc_from_localtime(dt, tz): 
    dt = dt.replace(tzinfo=tz) 
    _dt = tz.normalize(dt) 
    if dt.tzinfo != _dt.tzinfo: 
     # Houston, we have a problem... 
     # find out which one has a dst offset 
     if _dt.tzinfo.dst(_dt): 
      _dt -= _dt.tzinfo.dst(_dt) 
     else: 
      _dt += dt.tzinfo.dst(dt) 
    return _dt.astimezone(pytz.utc) 

Không cần phải nói hai phương pháp tạo ra kết quả khác nhau cho khá một vài Múi giờ.

Câu hỏi là - cách phù hợp là gì?

+0

Tôi ngạc nhiên mà không ai xóa 'Cảm ơn' ra khỏi cơ thể của câu hỏi. Hãy xem mất bao lâu để xóa nó! – Art

+0

Theo tính toán của tôi, chỉ có 897 ngày. – Will

+0

Cảm ơn bạn, Will, vì đã sai! – Art

Trả lời

19

Phương pháp đầu tiên của bạn dường như là phương pháp được chấp thuận và cần được DST biết.

Bạn có thể rút ngắn nó một chút, vì pytz.utc = pytz.timezone ('UTC'), nhưng bạn biết rằng đã :) đúng cách để

tz = timezone('US/Pacific') 
def toUTC(d): 
    return tz.normalize(tz.localize(d)).astimezone(pytz.utc) 

print "Test: ", datetime.datetime.utcnow(), " = ", toUTC(datetime.datetime.now()) 
+0

Tại sao phải chuẩn hóa()? là nó thực sự cần thiết? – kolypto

+1

@kolypto: Rõ ràng 'tz.normalize()' sẽ tính đến Thời gian tiết kiệm ánh sáng ban ngày và các phiền toái khác mà 'tz.localize()' không, như được giải thích trong các câu trả lời SO khác như [this one] (https: // stackoverflow .com/a/1379874/147320). – ewall

+2

@kolypto: một số giờ địa phương không tồn tại, ví dụ: khi đồng hồ địa phương nhảy về phía trước vào mùa xuân trong thời gian chuyển đổi sang mùa hè ở một số quốc gia (bán cầu bắc). 'tz.localize()' tôn trọng đối tượng 'd' (nó không thay đổi thời gian, nó chỉ cố gắng thêm một đối tượng tzinfo thích hợp) do đó' tz.normalize() 'là cần thiết để điều chỉnh thời gian không tồn tại. Mặc dù cả hai lần (trước/sau khi điều chỉnh) phải tương ứng với cùng thời gian UTC, tức là 'tz.normalize()' có thể là không cần thiết nếu tất cả chúng ta làm là chuyển đổi thời gian thành UTC như trong trường hợp này. – jfs

0

Sử dụng phương pháp đầu tiên. Không có lý do gì để phát minh lại bánh xe của chuyển đổi múi giờ

3

là gì chuyển đổi một thời gian ngây thơ và một tzinfo vào một thời gian utc?

This answer enumerates some issues with converting a local time to UTC:

from datetime import datetime 
import pytz # $ pip install pytz 

d = datetime(2009, 8, 31, 22, 30, 30) 
tz = pytz.timezone('US/Pacific') 

# a) raise exception for non-existent or ambiguous times 
aware_d = tz.localize(d, is_dst=None) 
## b) assume standard time, adjust non-existent times 
#aware_d = tz.normalize(tz.localize(d, is_dst=False)) 
## c) assume DST is in effect, adjust non-existent times 
#aware_d = tz.normalize(tz.localize(naive_d, is_dst=True)) 

# convert to UTC 
utc_d = aware_d.astimezone(pytz.utc) 
-2
import pytz 
    from django.utils import timezone 

    tz = pytz.timezone('America/Los_Angeles') 
    time = tz.normalize(timezone.now()) 
+0

không chính xác. Nếu 'USE_TZ = True' thì' timezone.now() 'trả về một datetime nhận biết trong UTC và do đó bạn không nên gọi' tz.normalize() 'trên nó. Nếu 'USE_TZ = False' thì django sử dụng múi giờ mặc định có thể khác với Mỹ/Los_Angeles và mã cũng sai trong trường hợp này. – jfs