500 Stimmen

Man kann offset-naive und offset-bewusste Zeitpunkte nicht subtrahieren

Ich habe eine zeitzonenbewusste timestamptz Feld in PostgreSQL. Wenn ich Daten aus der Tabelle ziehe, möchte ich die aktuelle Zeit subtrahieren, um das Alter zu ermitteln.

Das Problem, das ich habe, ist, dass beide datetime.datetime.now() y datetime.datetime.utcnow() scheinen Zeitzonen-unkorrekte Zeitstempel zurückzugeben, was dazu führt, dass ich diesen Fehler erhalte:

TypeError: can't subtract offset-naive and offset-aware datetimes 

Gibt es eine Möglichkeit, dies zu vermeiden (vorzugsweise ohne Verwendung eines Moduls eines Drittanbieters).

EDIT: Vielen Dank für die Vorschläge, jedoch versucht, die Zeitzone anzupassen scheint, mir Fehler zu geben.. so ich bin nur gehen, um Zeitzone nicht bewusst Zeitstempel in PG und immer einfügen mit verwenden:

NOW() AT TIME ZONE 'UTC'

Auf diese Weise sind alle meine Zeitstempel standardmäßig UTC (auch wenn es lästiger ist, dies zu tun).

13voto

Dave Punkte 1312

Die einfachste Antwort auf die im Titel gestellte Frage scheint zu fehlen:

naive_date.replace(tzinfo=aware_date.tzinfo) - aware_date

12voto

Ashok Joshi Punkte 418

Ich hatte auch das gleiche Problem. Dann habe ich nach langem Suchen eine Lösung gefunden.

Das Problem war, dass, wenn wir das datetime-Objekt von model oder form erhalten, es ist Offset-bewusst und wenn wir die Zeit durch das System erhalten, ist es Offset-naiv .

Ich habe also die aktuelle Zeit mit timezone.now() und importieren Sie die Zeitzone mit from django.utils import timezone und setzen die USE_TZ = Wahr in Ihrer Projekteinstellungsdatei.

6voto

erjiang Punkte 42668

Das psycopg2-Modul hat seine eigenen Zeitzonendefinitionen, also habe ich meinen eigenen Wrapper um utcnow herum geschrieben:

def pg_utcnow():
    import psycopg2
    return datetime.utcnow().replace(
        tzinfo=psycopg2.tz.FixedOffsetTimezone(offset=0, name=None))

und verwenden Sie einfach pg_utcnow wenn Sie die aktuelle Zeit zum Vergleich mit einer PostgreSQL timestamptz

6voto

John L. Stanley Punkte 71

Ich habe eine ganz einfache Lösung gefunden:

import datetime

def calcEpochSec(dt):
    epochZero = datetime.datetime(1970,1,1,tzinfo = dt.tzinfo)
    return (dt - epochZero).total_seconds()

Es funktioniert sowohl mit zeitzonenabhängigen als auch mit zeitzonenunabhängigen Datumswerten. Und es sind keine zusätzlichen Bibliotheken oder Datenbank-Workarounds erforderlich.

2voto

Joseph Coco Punkte 404

Ich habe gefunden timezone.make_aware(datetime.datetime.now()) ist in Django hilfreich (ich benutze 1.9.1). Leider kann man nicht einfach eine datetime Objekt offset-fähig ist, dann timetz() es. Sie müssen eine datetime und auf dieser Grundlage Vergleiche anstellen.

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X