J'ai un timestamptz
champ sensible au fuseau horaire dans PostgreSQL. Lorsque je tire des données du tableau, je veux ensuite soustraire le temps maintenant afin que je puisse obtenir son âge.
Le problème que je vais avoir est que les deux datetime.datetime.now()
et datetime.datetime.utcnow()
semblent revenir fuseau horaire horodatages pas au courant, ce qui conduit à me faire cette erreur:
TypeError: can't subtract offset-naive and offset-aware datetimes
Existe-t-il un moyen d'éviter cela (de préférence sans qu'un module tiers soit utilisé).
EDIT: Merci pour les suggestions, cependant essayer d'ajuster le fuseau horaire semble me donner des erreurs .. donc je vais juste utiliser des horodatages ignorés du fuseau horaire dans PG et toujours insérer en utilisant:
NOW() AT TIME ZONE 'UTC'
De cette façon, tous mes horodatages sont UTC par défaut (même si c'est plus ennuyeux de le faire).
datetime.timezone.utc
oupytz.utc
. Par exemple,1970-01-01 00:00:00
est ambigu et vous devez ajouter un fuseau horaire à désambiguïser:1970-01-01 00:00:00 UTC
. Vous voyez, vous devez ajouter de nouvelles informations; l'horodatage en lui-même est ambigu.utcnow
ne devrait pas renvoyer un objet naïf ou un horodatage sans fuseau horaire. D'après les documents, "Un objet conscient est utilisé pour représenter un moment précis qui n'est pas ouvert à l'interprétation". Toute heure en UTC remplit ce critère, par définition.La bonne solution consiste à ajouter les informations de fuseau horaire, par exemple, pour obtenir l'heure actuelle en tant qu'objet datetime conscient dans Python 3:
Sur les anciennes versions de Python, vous pouviez définir
utc
vous-même l'objet tzinfo (exemple de la documentation datetime):puis:
la source
Je sais que certaines personnes utilisent Django spécifiquement comme interface pour résumer ce type d'interaction avec la base de données. Django fournit des utilitaires qui peuvent être utilisés pour cela:
Vous devez configurer une infrastructure de paramètres Django de base, même si vous utilisez simplement ce type d'interface (dans les paramètres, vous devez inclure
USE_TZ=True
pour obtenir une date / heure consciente).En soi, cela est probablement loin d'être suffisant pour vous motiver à utiliser Django comme interface, mais il existe de nombreux autres avantages. D'un autre côté, si vous êtes tombé ici parce que vous manipuliez votre application Django (comme je l'ai fait), alors peut-être que cela aide ...
la source
USE_TZ=True
, pour obtenir un datetime conscient ici.+ timedelta(hours=5, minutes=30)
pour ISTCeci est une solution très simple et claire
Deux lignes de code
Conclusion: vous devez gérer vos variables datetime avec les mêmes informations de temps
la source
diff = datetime.now(timezone.utc) - your_timezone_aware_variable
fonctionne (et la(a - b)
formule ci-dessus est l'explication pourquoi(a - b)
peut fonctionner même si cea.tzinfo
n'est pas le casb.tzinfo
).Le module psycopg2 a ses propres définitions de fuseau horaire, j'ai donc fini par écrire mon propre wrapper autour d'utcnow:
et utilisez simplement
pg_utcnow
chaque fois que vous avez besoin de l'heure actuelle pour comparer avec un PostgreSQLtimestamptz
la source
J'ai également rencontré le même problème. Ensuite, j'ai trouvé une solution après de nombreuses recherches.
Le problème était que lorsque nous obtenons l'objet datetime à partir d'un modèle ou d'une forme, il est conscient du décalage et si nous obtenons l'heure par le système, il est naïf .
Donc, ce que j'ai fait, c'est que j'ai obtenu l'heure actuelle en utilisant timezone.now () et en important le fuseau horaire à partir de django.utils import timezone et en mettant USE_TZ = True dans votre fichier de paramètres de projet.
la source
J'ai trouvé une solution ultra simple:
Il fonctionne avec des valeurs datetime sensibles au fuseau horaire et naïves au fuseau horaire. Et aucune bibliothèque ou solution de contournement de base de données supplémentaire n'est requise.
la source
Je l'ai trouvé
timezone.make_aware(datetime.datetime.now())
utile dans Django (je suis sur 1.9.1). Malheureusement, vous ne pouvez pas simplement rendre undatetime
objet sensible à l'offset, alorstimetz()
. Vous devez faire undatetime
et faire des comparaisons sur la base de cela.la source
Y a-t-il une raison urgente pour laquelle vous ne pouvez pas gérer le calcul de l'âge dans PostgreSQL lui-même? Quelque chose comme
la source
Je sais que c'est vieux, mais je pensais simplement ajouter ma solution au cas où quelqu'un la trouverait utile.
Je voulais comparer le datetime naïf local avec un datetime conscient d'un serveur de temps. J'ai essentiellement créé un nouvel objet datetime naïf en utilisant l'objet datetime conscient. C'est un peu un hack et n'a pas l'air très joli mais fait le travail.
... voici le fudge ...
la source
utc_to_local()
ma réponse renvoie l'heure locale comme un objet datetime conscient (c'est du code Python 3.3+)delta = response.tx_time - time.time()
.