2015-12-02 6 views
5

Ich habe intensiv mit Daten in Python/Django gearbeitet. Um verschiedene Anwendungsfälle zu lösen, habe ich blind verschiedene Ansätze getestet, bis einer von ihnen funktionierte, ohne die Logik zu verstehen, die dahinter steckt, wie die verschiedenen Funktionen funktionieren.Django/Python - Zerstreuung der Verwirrung in Bezug auf Daten und Zeitzonenbewusstsein

Jetzt ist es Crunch Time. Ich möchte ein paar Fragen bezüglich der Feinheiten von Daten und Zeitzonen in Django/Python stellen.

Wie interpretiere ich ein datetime Objekt, das bereits eine Zeitzone hat?

Um zu klären, sagen wir, ich folgendes tun:

>>> generate_a_datetime() 
datetime.datetime(2015, 12, 2, 0, 0, tzinfo=<DstTzInfo 'Canada/Eastern' LMT-1 day, 18:42:00 STD>) 
>>> 

Die Konsolenausgabe mir zweideutig erscheint:

Q1) Dieses datetime Objekt sagt, ist 2015-12-02 - Was die Erzählung generate_a_datetime Funktion ist mich? Sagt es, dass "ein Mann, der in Ostkanada steht, seinen Kalender betrachtend, sieht" 2015-12-02 "? ODER bedeutet es " Dieses ist "2015-12-02 UTC" ... aber nicht vergessen dies die östlichen Kanada-Zeitzone anzupassen“

django.utils.timezone.make_aware mich verwirrt

zum Beispiel:.

>>> from django.utils import timezone 
>>> import pytz 
>>> tz = pytz.timezone('Canada/Eastern') 
>>> now_unaware = datetime.datetime.now() 
>>> now_aware_with_django = timezone.make_aware(now_unaware, tz) 
>>> now_aware_with_datetime = now_unaware.replace(tzinfo=tz) 
>>> now_unaware 
datetime.datetime(2015, 12, 2, 22, 1, 19, 564003) 
>>> now_aware_with_django 
datetime.datetime(2015, 12, 2, 22, 1, 19, 564003, tzinfo=<DstTzInfo 'Canada/Eastern' EST-1 day, 19:00:00 STD>) 
>>> now_aware_with_datetime 
datetime.datetime(2015, 12, 2, 22, 1, 19, 564003, tzinfo=<DstTzInfo 'Canada/Eastern' LMT-1 day, 18:42:00 STD>) 
>>> 

die Objekte now_aware_with_django und now_aware_with_datetime scheinen zu verhalten ähnlich, aber ihre Konsolenausgabe legt nahe, dass sie anders sind.

Q2) Was ist der Unterschied zwischen now_aware_with_django und now_aware_with_datetime?

Q3) Woher weiß ich, ob ich timezone.make_aware oder datetime.replace verwenden muss?

Naive Datetimes gegen UTC Datetime

UTC bedeutet, dass es keine Änderung des Zeitwertes ist. "Naiv" scheint zu bedeuten, dass mit der Zeit keine Zeitzone verbunden ist.

Q4) Was ist der Unterschied zwischen naiven und UTC-Datumsangaben? Es sieht so aus, als ob sie genau gleich sind - und keine Veränderung des tatsächlichen Zeitwerts bewirken.

Q5) Woher weiß ich, wann ich naive Zeiten verwenden möchte und wann ich UTC-Zeiten verwenden möchte?

Wenn ich eine Antwort auf alle 5 Fragen bekommen könnte, wäre das positiv hervorragend. Vielen Dank!

Antwort

1

Q1) Dieses Datetime-Objekt sagt, das ist 2015-12-02 - Was sagt mir die Funktion generate_a_datetime? Heißt das, dass "ein Mann, der im Osten Kanadas steht und auf seinen Kalender schaut," 2015-12-02 "sieht? Oder bedeutet das" Das ist "2015-12-02 UTC" ... aber vergessen Sie nicht, dies anzupassen in die Ost-Kanada Zeitzone! "

Die erste Interpretation war korrekt.Der Zeitzone-aware Datetime bereits „angepasst“ für Sie und die Tzinfo sagen Ihnen nur, die es Zeitzone angegeben in.

Q2) Was ist der Unterschied zwischen now_aware_with_django und now_aware_with_datetime?

Für den ersten Fall, dass Sie schaffen eine Datetime, die den gleichen Zeitpunkt als ‚naiv‘ vorausgesetzt die naive in Ihrer lokalen Zeitzone war einer, und das ist darstellt.

Für den zweiten Fall, Sie sagen, dass der naive war bereits in der Zeitzone, die Sie zur Verfügung stellen, und dann Sie nur auf die TZinfo heften.

Q3) Wie kann ich wissen, ob ich timezone.make_aware oder datetime.replace?

Nun verwenden müssen, da sie verschiedene Dinge tun, müssen Sie wissen, was Sie zu tun, um zu wissen, sich versuchen, die zu verwenden. Wenn Sie von einer naiven Zeitzone (in Ihrer lokalen Zeit) in eine andere Zeitzone konvertieren möchten, können Sie make_aware dafür verwenden. Wenn du bereits die Zeitzone deiner naiven Datetime kennst, benutzt du einfach die Ersetzung (oder schaue localize in pytz an, die etwas vorsichtiger ist).

Hinweis: in der Regel, wenn Sie irgendwelche naiven Datumsangaben rumhängen in erster Linie haben, tun Sie etwas falsch früher, und Sie sollten das früher fangen. Versuchen Sie, sie an der Grenze Ihrer App zu sensibilisieren - ich werde mehr dazu in Q5 sagen.

Q4) Was ist der Unterschied zwischen naiven und UTC-Datumsangaben? Es sieht so aus, als ob sie genau gleich sind - und keine Veränderung des tatsächlichen Zeitwerts bewirken.

Ein naives Datetime ist nur eine Datetime, die dir nicht sagt, in welcher Zeitzone es ist. Es ist nicht unbedingt UTC, es könnte alles sein. Es ist ähnlich wie Bytestrings und Unicode - Sie müssen wissen, was die Codierung ist, um zu sagen, was die decodierten Bytes sagen. Für ein naives Datetime müssen Sie wissen, in welcher Zeitzone es ist, bevor Sie sagen können, wie viel Zeit es tatsächlich darstellt. In diesem Sinne liefert eine UTC-Datetime mehr Informationen als eine naive Datetime.

UTC ist koordinierte universelle Zeit, Schuld der Französisch für die seltsame Abkürzung. Zeitzonen werden normalerweise als von UTC um eine ganze Zahl von Stunden abweichend definiert, und für alle praktischen Zwecke kann man sich UTC als die Zeitzone vorstellen, die um 0 Stunden von UTC abweicht. Und es ist wie GMT ohne Sommerzeit-Unsinn.

Q5) Woher weiß ich, wann ich naive Zeiten benutzen möchte und wann ich UTC-Zeiten benutzen möchte?

Hier gibt es Meinungsverschiedenheiten. Meine Empfehlung ist, immer mit allem in UTC innerhalb Ihrer App zu arbeiten (und UTC nur in den Datenbanken zu speichern!). Wenn Daten zu Datum und Uhrzeit in Ihre App eingegeben werden, jedoch in Ihre App eingegeben werden, vergewissern Sie sich, dass sie korrekt in UTC konvertiert wurde. Dies bedeutet auch, dass überall innerhalb Ihre App, die datetime.now() (die eine naive Datetime mit der "fehlenden" tzinfo ist, die die lokale Zeitzone der Maschine sein sollte) statt datetime.utcnow() (was eine naive Datetime in UTC ist) oder noch besser datetime.now(tz=pytz.utc) (das ist Zeitzone bewusst).

Ändern Sie nur in der lokalen Zeitzone am "Display" Ende Ihrer App.Sie können dies normalerweise mit Schablonen-Tags oder sogar mit clientside js tun.

+0

Perfekt. +1 für die praktischen Empfehlungen! –