2016-04-01 10 views
3

Angenommen, ich erhalte in einer Anfrage ein beliebiges Datetime-Objekt, das aus einer beliebigen Zeitzone kommen könnte - ich weiß nicht, welches. Aus Gründen der Beispiel so tun, als es von der OstküsteSo konvertieren Sie eine Datetime von einer beliebigen Zeitzone in eine andere beliebige Zeitzone

import pytz 
from colander import iso8601 
... 
    ests1 = iso8601.parse_date('2016-04-01T00:00:00.0000-04:00') 

vorgeben ests1 ist das Objekt, das

Mit pytz in

kommt kommt, kann ich etwas herausfinden, darüber Zeitzone ist

etz = ests1.timetz() # 00:00:00-04:00 
    etzi = ests1.tzinfo # <FixedOffset '-04:00' datetime.timedelta(-1, 72000)> 
    etzn = ests1.tzname() # '-04:00' # EST 
    edst = ests1.dst() # '0:00:00' 

Beachten Sie, dass, egal, welches Datum ist ests1 ist - dst() scheint immer den gleichen Wert zurück

Ich würde gerne so etwas tun:

psts1 = pytz.timezone(etzn 
        ).localize(dtime.datetime.fromtimestamp(ests1) 
        ).astimezone(pytz.timezone('US/Pacific')) 

aber das führt nur in

UnknownTimeZoneError: '-04:00' 

Ich habe auch schon versucht, diese:

def convert_dt_to_pstz(dt): 
    pstoffset = -25200 # -7 * 60 * 60 - but what about DST? how do we tell which offset to use? -8 or -7 
    return dt.astimezone(tzoffset(None,pstoffset)) # convert to PST 

Aber das Problem mit dieser ist, ich weiß nicht, wie wenn das Datum Bedürfnis zu sagen, für die Sommerzeit angepasst werden.

ich dies auch versucht:

utc_date = ests1.astimezone(pytz.utc) # 2016-04-01T04:00:00+00:00 
    ptz = pytz.timezone('US/Pacific') 
    new_date = utc_date.replace(tzinfo=ptz) # 2016-04-01T04:00:00-07:53 

Aber Blick auf das seltsame Ergebnis für NEW_DATE: -07: 53 ??

Bitte beachten Sie, dass ich keine Informationen verwenden kann, um „jetzt“ oder den Standort des Servers entsprechen, wie es

+3

Beachten Sie, dass ein reiner numerischer Offset keine Informationen darüber gibt, ob die Sommerzeit aktiv ist oder nicht. Sie müssen mehr Informationen darüber wissen, wie die Zeit generiert wurde, um daraus abzuleiten, dass "-04: 00" aus der US/Eastern-Zeitzone und nicht etwa aus Brasilien stammt. Das ist jedoch ein Detail - ich denke, Ihre Frage ist interessant. Ein Teil der Antwort lautet "Umwandlung in UTC aus der Quellzeitzone"; In Zielzeitzone von UTC konvertieren. Es gibt dann Probleme mit dem genauen Ausführen dieser Konvertierungen. –

+0

von iso8601 Format können Sie nicht sagen, es wird sagen -0400 für EDT und -0500 für EST, aber -0400 könnte AMT sowie – scope

+0

@ scope: Nun, es gibt Möglichkeiten, Sommerzeit zu bestimmen - aber es ist komplex und ich frage mich, ob da draußen schon etwas gebaut ist, das den Job machen wird.Ich habe es noch nicht gefunden – slashdottir

Antwort

3

um eine Zeitzone-aware datetime Objekt in einer anderen Zeitzone zu konvertieren, use datetime.astimezone() method:

pacific_time = ests1.astimezone(pytz.timezone('US/Pacific')) 

Im Allgemeinen pytz docs empfehlen pytz.timezone('US/Pacific').normalize() auf das Ergebnis zu nennen, aber Sie tun es hier nicht brauchen, weil ests1 Zeitzone hat sich zu einem festen utc Offset.

+0

, das scheint zu arbeiten, danke – slashdottir

0

Ich denke, dass ich es dieses Mal richtig verstanden habe überall sein könnte:

from datetime import datetime as dtime 
import pytz 
from colander import iso8601 

ests1 = iso8601.parse_date('2016-04-01T00:00:00.0000-04:00') 
epoch = dtime(1970, 1, 1, tzinfo=pytz.UTC)   # 1970-01-01T00:00:00+00:00 
ept = (ests1 - epoch).total_seconds()    # 1459483200.0 

utc_date = dtime.fromtimestamp(ept, tz=pytz.UTC) # 2016-04-01T04:00:00+00:00 
ptz = pytz.timezone('US/Pacific') 
pst_date = dtime.fromtimestamp(ept, tz=ptz)   # 2016-03-31T21:00:00-07:00 

ests2 = iso8601.parse_date('2016-02-01T00:00:00.0000-04:00') 
ept2 = (ests2 - epoch).total_seconds()    # 1454299200.00 

utc_date2 = dtime.fromtimestamp(ept2, tz=pytz.UTC) # 2016-02-01T04:00:00+00:00 
pst_date2 = dtime.fromtimestamp(ept2, tz=ptz)  # 2016-01-31T20:00:00-08:00 

so, es scheint so einfach zu sein, wie

def convert_to_tz(dt,tz_new): 
    seconds = (dt - epoch).total_seconds() 
    return dtime.fromtimestamp(seconds, tz=tz_new) 
Verwandte Themen