2009-08-31 13 views
26

Jaki jest właściwy sposób zamiany czasu naiwnego i tzinfo na czas UTC? Say mam:konwersja pytz utc

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

Pierwszy sposób pytz inspirowane:

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

Drugi sposób, z 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) 

trzeba dodawać te dwie metody dają różne wyniki dla sporo strefy czasowe.

Pytanie brzmi - jaka jest właściwa droga?

+0

Jestem zdziwiony, że nikt usunięte 'Thanks' z ciała w rachubę. Zobaczmy, ile czasu potrzeba, aby go usunąć! – Art

+0

Według moich obliczeń, tylko 897 dni. – Will

+0

Dziękuję, Will, za naprawienie błędu! – Art

Odpowiedz

19

Twoja pierwsza metoda wydaje się być zatwierdzona i powinna być zgodna z DST.

Można go skrócić odrobinę, ponieważ pytz.utc = pytz.timezone ('UTC'), ale wiedział, że już :)

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

Dlaczego warto znormalizować()? czy to naprawdę konieczne? – kolypto

+1

@kolypto: Podobno 'tz.normalize()' będzie uwzględniało czas letni i inne niedogodności, których 'tz.localize()' nie spełnia, jak wyjaśniono w innych odpowiedziach SO takich jak [this one] (https: // stackoverflow .com/a/1379874/147320). – ewall

+2

@kolypto: niektóre lokalne czasy nie istnieją, np. Kiedy zegar lokalny przeskoczy do przodu wiosną podczas przejścia na czas letni w niektórych krajach (półkuli północnej). 'tz.localize()' respects dany obiekt 'd' (nie zmienia czasu, próbuje jedynie dodać odpowiedni obiekt tzinfo), dlatego' tz.normalize() 'jest konieczne, aby dostosować nieistniejące czasy. Chociaż oba czasy (przed/po korekcie) powinny odpowiadać temu samemu czasowi UTC, tzn. 'Tz.normalize()' może być niepotrzebne, jeśli wszystko, co robimy, konwertuje czas na UTC, jak w tym przypadku. – jfs

0

Użyj pierwszej metody. Nie ma powodu, aby odnawiać koło konwersji strefy czasowej.

3

Co jest właściwym sposobem przekształcić naiwny czas i tzinfo w czas 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

jest niepoprawna. Jeśli 'USE_TZ = True' to' timezone.now() 'zwraca świadome dane w UTC i dlatego nie powinieneś wywoływać' tz.normalize() 'na tym. Jeśli 'USE_TZ = False', wówczas django używa domyślnej strefy czasowej, która może być inna niż America/Los_Angeles i kod również jest błędny w tym przypadku. – jfs

Powiązane problemy