2009-08-31 35 views
26

Bir naif zamanı ve tzinfo bir UTC saatine dönüştürmenin doğru yolu nedir? Ben olduğunu varsayalım:pytz utc dönüşümü

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

İlk yolu, pytz ilham:

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

İkinci yol, UTCDateTimeField bu iki yöntem epeyce farklı sonuçlar üretmek Söylemeye gerek yok

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) 

dan Zaman dilimleri.

Soru şudur - doğru yol nedir?

+0

Ben kimsenin söz gövdesinden 'Teşekkür' silindi şaşırıyorum. Bakalım onu ​​kaldırmanın ne kadar sürdüğünü görelim! – Art

+0

Hesaplamalarımda sadece 897 gün. – Will

+0

Teşekkür ederim, Will, hatayı düzeltmek için! – Art

cevap

19

tekerleğini yeniden icat etmek için bir neden yoktur. İlk yönteminiz onaylanmış olanıdır ve DST'nin farkında olması gerekir.

Sen pytz.utc = pytz.timezone ('UTC') beri bunu bir nebze kısaltabilir, ancak

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

Neden normalize()? gerçekten gerekli mi? – kolypto

+1

@kolypto: Görünüşe göre 'tz.normalize()', Günışığı Tasarrufu Zamanı'nı ve tz.localize() 'ın diğer SO cevaplarında (bu []] (https: // stackoverflow) com/a/1379874/147320). – ewall

+2

@kolypto: Bazı yerel zamanlar, örneğin, yerel saatin bazı ülkelerde (kuzey yarımküre) yaz mevsimine geçiş sırasında ilkbaharda ileriye atladığında mevcut değildir. 'tz.localize()' saygılar verilen d 'nesnesini (zamanını değiştirmez, sadece uygun bir tzinfo nesnesi eklemeyi dener) bu nedenle 'tz.normalize()' mevcut olmayan zamanları ayarlamak için gereklidir. Her iki seferde (ayarlamadan önce/sonra) aynı UTC zamanına karşılık gelmesine rağmen, tek yapmamız gereken, bu durumda olduğu gibi zamanı UTC'ye çevirmekse, gereksizdir (tz.normalize()). – jfs

0

İlk yöntemi kullanın. Zaman dilimi dönüşümü

3

doğru yolu nedir zaten :) biliyordu naif bir zamanı ve tzinfo bir utc zamana dönüştürmek?

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

yanlış. Eğer USE_TZ = True 'ise' timezone.now() ', UTC'de bir tarih bilgisini döndürür ve bu nedenle üzerine' tz.normalize() 'dememelisiniz. 'USE_TZ = False' ise, django, America/Los_Angeles'den farklı olabilecek varsayılan zaman dilimini kullanır ve bu durumda kod da yanlıştır. – jfs