Nie można odjąć daty offsetowej i offsetowej
Mam pole timezone aware timestamptz
w PostgreSQL. Kiedy wyciągam dane z tabeli, a następnie chcę odjąć czas teraz, więc mogę uzyskać to wiek.
Problem, który mam polega na tym, że zarówno datetime.datetime.now()
jak i datetime.datetime.utcnow()
wydają się zwracać nieświadome strefy czasowej znaczniki czasu, co powoduje, że dostaję ten błąd:
TypeError: can't subtract offset-naive and offset-aware datetimes
Czy istnieje sposób, aby tego uniknąć (najlepiej bez użycia zewnętrznego modułu).
EDIT: dzięki za sugestie, jednak staram się dostosować Strefa czasowa wydaje się dawać mi błędy.. więc po prostu użyję timezone timestamps w PG i zawsze wstawiam używając:
NOW() AT TIME ZONE 'UTC'
W ten sposób wszystkie moje znaczniki czasu są domyślnie UTC(nawet jeśli jest to bardziej denerwujące).
11 answers
Czy próbowałeś usunąć świadomość strefy czasowej?
Z http://pytz.sourceforge.net/
naive = dt.replace(tzinfo=None)
Może być również konieczne dodanie konwersji strefy czasowej.
Edit: proszę pamiętać o wieku tej odpowiedzi. Odpowiedź dotycząca dodania informacji o strefie czasowej zamiast usuwania jej w Pythonie 3 znajduje się poniżej. https://stackoverflow.com/a/25662061/93380
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2020-09-24 15:07:07
Poprawnym rozwiązaniem jest dodanie informacji o strefie czasowej, np. aby uzyskać bieżący czas jako świadomy obiekt datetime w Pythonie 3:
from datetime import datetime, timezone
now = datetime.now(timezone.utc)
W starszych wersjach Pythona można samemu zdefiniować obiekt utc
tzinfo (przykład z datetime docs):
from datetime import tzinfo, timedelta, datetime
ZERO = timedelta(0)
class UTC(tzinfo):
def utcoffset(self, dt):
return ZERO
def tzname(self, dt):
return "UTC"
def dst(self, dt):
return ZERO
utc = UTC()
Wtedy:
now = datetime.now(utc)
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-09-04 09:37:14
Wiem, że niektórzy ludzie używają Django specjalnie jako interfejsu do abstrakcji tego typu interakcji z bazą danych. Django dostarcza narzędzia, które mogą być użyte do tego:
from django.utils import timezone
now_aware = timezone.now()
Musisz skonfigurować podstawową infrastrukturę ustawień Django, nawet jeśli używasz tylko tego typu interfejsu(w Ustawieniach musisz dołączyć USE_TZ=True
, Aby uzyskać świadomy datetime).
Samo w sobie, prawdopodobnie nie jest to wystarczająco blisko, aby zmotywować cię do używania Django jako interfejsu, ale jest wiele innych korzyści. Z drugiej strony, jeśli natknąłeś się tutaj, ponieważ niszczyłeś swoją aplikację Django( tak jak ja), to może to pomoże...
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-01-21 16:23:52
Jest to bardzo proste i jasne rozwiązanie
dwie linijki kodu
# First we obtain de timezone info o some datatime variable
tz_info = your_timezone_aware_variable.tzinfo
# Now we can subtract two variables using the same time zone info
# For instance
# Lets obtain the Now() datetime but for the tz_info we got before
diff = datetime.datetime.now(tz_info)-your_timezone_aware_variable
Wniosek: musisz mange swoje zmienne datetime z tym samym czasie info
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2019-07-30 11:08:17
Ja również stanąłem przed tym samym problemem. Potem znalazłem rozwiązanie po wielu poszukiwaniach .
Problem polegał na tym, że gdy otrzymujemy obiekt datetime z modelu lub postaci, jest to offset aware , a jeśli otrzymamy czas przez system, to jest to offset naive.
Więc to, co zrobiłem, to otrzymałem bieżący czas używając strefy czasowej.now () i zaimportuj strefę czasową przez z django.utils importuje strefę czasową i umieszcza USE_TZ = True w pliku ustawień projektu.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-02-22 08:01:18
Moduł psycopg2 ma własne definicje stref czasowych, więc skończyło się na pisaniu własnego wrappera wokół utcnow:
def pg_utcnow():
import psycopg2
return datetime.utcnow().replace(
tzinfo=psycopg2.tz.FixedOffsetTimezone(offset=0, name=None))
I po prostu użyj pg_utcnow
, gdy potrzebujesz bieżącego czasu, aby porównać z PostgreSQL timestamptz
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-01-29 13:43:51
Wymyśliłem ultra-proste rozwiązanie:
import datetime
def calcEpochSec(dt):
epochZero = datetime.datetime(1970,1,1,tzinfo = dt.tzinfo)
return (dt - epochZero).total_seconds()
Działa zarówno z wartością timezone-aware, jak i timezone-naiwne datetime. Nie są wymagane żadne dodatkowe biblioteki ani obejścia w bazie danych.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-05-15 20:39:59
Znalazłem timezone.make_aware(datetime.datetime.now())
jest pomocny w django(jestem na 1.9.1). Niestety nie można po prostu zrobić datetime
obiekt offsetowy świadomy, a następnie timetz()
to. Musisz zrobić datetime
i dokonać porównań na tej podstawie.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-07-25 19:39:16
Czy Jest jakiś pilny powód, dla którego nie możesz poradzić sobie z obliczaniem wieku w samym PostgreSQL? Coś jak
select *, age(timeStampField) as timeStampAge from myTable
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2019-08-14 10:09:43
Wiem, że to stare, ale pomyślałem, że dodam moje rozwiązanie na wypadek, gdyby ktoś uznał je za przydatne.
Chciałem porównać lokalny naiwny datetime ze świadomym datetime z serwera czasowego. W zasadzie stworzyłem nowy naiwny obiekt datetime przy użyciu świadomego obiektu datetime. To trochę hack i nie wygląda bardzo ładnie, ale robi robotę.
import ntplib
import datetime
from datetime import timezone
def utc_to_local(utc_dt):
return utc_dt.replace(tzinfo=timezone.utc).astimezone(tz=None)
try:
ntpt = ntplib.NTPClient()
response = ntpt.request('pool.ntp.org')
date = utc_to_local(datetime.datetime.utcfromtimestamp(response.tx_time))
sysdate = datetime.datetime.now()
...nadchodzi krówka...
temp_date = datetime.datetime(int(str(date)[:4]),int(str(date)[5:7]),int(str(date)[8:10]),int(str(date)[11:13]),int(str(date)[14:16]),int(str(date)[17:19]))
dt_delta = temp_date-sysdate
except Exception:
print('Something went wrong :-(')
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-04-29 16:24:36
Nie potrzebujesz niczego poza std libs
datetime.datetime.now().astimezone()
Jeśli po prostu zastąpisz strefę czasową, nie dostosujesz czasu. Jeśli Twój system jest już UTC to .replace (TZ='UTC') jest w porządku.
>>> x=datetime.datetime.now()
datetime.datetime(2020, 11, 16, 7, 57, 5, 364576)
>>> print(x)
2020-11-16 07:57:05.364576
>>> print(x.astimezone())
2020-11-16 07:57:05.364576-07:00
>>> print(x.replace(tzinfo=datetime.timezone.utc)) # wrong
2020-11-16 07:57:05.364576+00:00
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2020-11-16 15:13:14