Hi,
gibt es eine Möglichkeit Zeiten von Django so zu ändern, dass eine vorher definierte Zeitzone für die Anzeige genutzt wird (oder die des Browser OS, wenn das übertragen werden sollte)? In settings.TIME_ZONE kann man zwar die Zeitzone einstellen, zu der Django automatisch sämtliche Zeitangaben konvertiert, aber das bringt mir nicht viel, da die Seite in verschiedenen Zeitzonen arbeiten soll und jeweils die lokale Zeit angezeigt werden soll (speichere sämtliche Zeitangaben in GMT).
Was ich nun nun bräuchte wäre evtl. ein (session-abhängiger) Filter, der zur richtigen Zeitzone konvertiert...
Irgendwelche Ideen?
Django: Timezone
Zeitzonen in Python erfordern erstmal ein neues Paket: pytz. Dummerweise kann Python in der Standardinstallation nicht mit Zeitzonen umgehen. Dann würde ich einfach in einem UserProfile den Benutzer seine Lieblingszeitzone einstellen lassen und diese dann über den in der Session gemerkten User zu berücksichtigen. Vielleicht hilft dir ja auch http://www.djangosnippets.org/snippets/183/ oder http://code.google.com/p/django-timezones/
Stefan
Stefan
Vielen Dank für den Hinweis. Den Filter konnte ich auch schon implementieren, aber so recht gefällt mir die Lösung noch nicht, da jedes mal das User Objekt im Template mitgegeben werden muss.
Das kann zwar noch vereinfacht werden, damit man nicht jedes Mal bei der HttpResponse den user explizit mitgeben muss:
aber trotzdem scheint mir das Übergeben des Users im Template überflüssig. Gibt es vielleicht die Möglichkeit den User, der das soeben generierte Template abfragt innerhalb der Filter-Funktion zu ermitteln?
Vielen Dank.
Code: Alles auswählen
from django import template
def user_timezone(value, user):
# timezone conversion
pass
register = template.Library()
register.filter('user_timezone', user_timezone)
Code: Alles auswählen
# settings.py
TEMPLATE_CONTEXT_PROCESSORS = (
'mysite.processor_file_name.user'
)
# mysite/processor_file_name.py
def user(request):
return {'user':request.user }
Vielen Dank.
-
- User
- Beiträge: 996
- Registriert: Mittwoch 9. Januar 2008, 13:48
Hm. Du könntest einen Hack zusammenschrauben, aber toll wäre das auch nicht:
Dann passiert zwar im Prinzip das Selbe, allerdings musst du nur noch `article.usertime|user_timezone` machen. Optional könntest du den Filter gleich in die Methode `usertime` einbauen, dann ist alles was du schreibst `article.usertime`. Oder so.
Code: Alles auswählen
# models
class YourModel:
@property
def usertime(self):
return (self.timestamp, self.user)
Vielleicht ist es mit einem Custom-Tag einfacher? Z.B. {% usertime article.create_at %}. Der Tag hätte Zugriff auf den Kontext und könnte sich dort den per Request-Prozessor (dafür gibt es übrigens schon einen fertigen) in den Kontext eingetragenen User herausholen.
Stefan
Stefan
Snippet 183 und django-timezones find ich auch nicht so gut. Vor allem wenn man sich das Alter des Snippets anschaut. An "Django-Timezones" wird zwar aktuell gebaut (siehe SVN-Repo), gefällt mir aber auch nicht so gut. Ich benutze "Django-Timezones" allerdings wegen des TimeZoneField. Bin zu faul das mit PyTZ selber zu machen.
Das gesamte User-Objekt mit in den Context zu packen finde ich, ehrlich gesagt, fragwürdig. Das schließt, soweit ich weiß, alle Relationen ein. Mit Kanonen auf Spatzen geschossen... Das Wort "Sicherheit" sei hier auch mal kurz erwähnt, nebenbei. Und vor allem braucht man nicht immer den User. Zudem: Spart DB-Abfragen...
Per Middleware kann man ja z.B. die Sprache nach den Einstellungen des Users einstellen... Da würde ich auch gleich die Zeitzone irgendwo hin packen. Allerdings unabhängig vom "User", in die Session meiner Meinung nach. Oder gleich in den Request, der ist ja immer verfügbar. Ob das so klug ist frag ich mich allerdings gerade auch.... Babeldjango macht allerdings genau das per Middleware und bringt auch Filter mit, um die Zeit ins rischdische Format zu formatieren. Locale = de-de, Datum = 01.12.2345
Bezüglich User-Einstellungen und Middleware würd ich nen Blick auf Pinax werfen. Im SVN unter so genannten "lokalen Applikationen" (glaub ich) findet man in einer App namens misc (oder woanders) eine LocaleMiddleware die bei jedem eingeloggtem User die Sprache einstellt...
Dann stellt sich da noch eine Frage: Wenn der User Zeiten oder Datum mit Zeitangaben (DATETIME oder TIME) in Formularen macht, denkt er doch bestimmt, dies innerhalb seiner Zeit-Zone zu machen. Was passiert dann bei der Verarbeitung? Will man in jeder View die Zeit von Hand anfassen und in die richtige Zeitzone konvertieren? Heiden-Arbeit bei größeren Projekten, oder?
Das zu lösen finde ich viel spannender!!!
Ich bin ja dafür, das Django das "unter der Haube" löst... Diskussion läuft da schon seit längerem. Dann hätte sich das Thema im Forum hier eh von selbst erledigt.
Das gesamte User-Objekt mit in den Context zu packen finde ich, ehrlich gesagt, fragwürdig. Das schließt, soweit ich weiß, alle Relationen ein. Mit Kanonen auf Spatzen geschossen... Das Wort "Sicherheit" sei hier auch mal kurz erwähnt, nebenbei. Und vor allem braucht man nicht immer den User. Zudem: Spart DB-Abfragen...
Per Middleware kann man ja z.B. die Sprache nach den Einstellungen des Users einstellen... Da würde ich auch gleich die Zeitzone irgendwo hin packen. Allerdings unabhängig vom "User", in die Session meiner Meinung nach. Oder gleich in den Request, der ist ja immer verfügbar. Ob das so klug ist frag ich mich allerdings gerade auch.... Babeldjango macht allerdings genau das per Middleware und bringt auch Filter mit, um die Zeit ins rischdische Format zu formatieren. Locale = de-de, Datum = 01.12.2345
Bezüglich User-Einstellungen und Middleware würd ich nen Blick auf Pinax werfen. Im SVN unter so genannten "lokalen Applikationen" (glaub ich) findet man in einer App namens misc (oder woanders) eine LocaleMiddleware die bei jedem eingeloggtem User die Sprache einstellt...
Dann stellt sich da noch eine Frage: Wenn der User Zeiten oder Datum mit Zeitangaben (DATETIME oder TIME) in Formularen macht, denkt er doch bestimmt, dies innerhalb seiner Zeit-Zone zu machen. Was passiert dann bei der Verarbeitung? Will man in jeder View die Zeit von Hand anfassen und in die richtige Zeitzone konvertieren? Heiden-Arbeit bei größeren Projekten, oder?
Das zu lösen finde ich viel spannender!!!
Ich bin ja dafür, das Django das "unter der Haube" löst... Diskussion läuft da schon seit längerem. Dann hätte sich das Thema im Forum hier eh von selbst erledigt.
Das user object ist schon im Context! (zumindest so lang du http://docs.djangoproject.com/en/dev/re ... rs-request enablest). Zugriff hast du darauf über request.user. Django macht so oder so jeden request eine Db Abfrage für den User, und nein relations werden erst geladen wenn du auf sie zugreifst, ala request.user.groups...tarak hat geschrieben: Das gesamte User-Objekt mit in den Context zu packen finde ich, ehrlich gesagt, fragwürdig. Das schließt, soweit ich weiß, alle Relationen ein. Mit Kanonen auf Spatzen geschossen... Das Wort "Sicherheit" sei hier auch mal kurz erwähnt, nebenbei. Und vor allem braucht man nicht immer den User. Zudem: Spart DB-Abfragen...
Und nein Sicherheit braucht man hier nicht zu erwähnen...
Nein ist es normalerweise nicht, man schreibt sich 2,3 Funktionen und konvertiert dann einfach, im Grunde könnte schon das Feld im Formular diese Aufgabe übernehmen (def clean, anyone?). Und selbst bei Modelforms kannst du die Felder überschreiben, also ist das fast keine Arbeit.Dann stellt sich da noch eine Frage: Wenn der User Zeiten oder Datum mit Zeitangaben (DATETIME oder TIME) in Formularen macht, denkt er doch bestimmt, dies innerhalb seiner Zeit-Zone zu machen. Was passiert dann bei der Verarbeitung? Will man in jeder View die Zeit von Hand anfassen und in die richtige Zeitzone konvertieren? Heiden-Arbeit bei größeren Projekten, oder?
Wo? Link bitte.Ich bin ja dafür, das Django das "unter der Haube" löst... Diskussion läuft da schon seit längerem. Dann hätte sich das Thema im Forum hier eh von selbst erledigt.
Gibt keinen bestimmten Link... Hab mir mit den Zeitzonen die selben Gedanken gemacht wie Lunas und herum gesucht. Mehrere Tage lang Mailinglisten gelesen, gegoogelt, etc... Ist mein "Gesamt-Eindruck" von der Problematik. Die Django-Entwickler sind sich des Problems bewusst, meiner Erinnerung nach war die Aussage da: Design decision needed (kann mich auch irren)...Wo? Link bitte.
Kann man abstellen. Will jetzt hier nicht theoretisch werden. Ich bleib dabei, will mich nicht auf request.user verlassen. Zeitzonen gehen auch ohne eingeloggten user...Django macht so oder so jeden request eine Db Abfrage für den User
Danke für das klären meiner Frage wegen relations, Apollo13!!! Hat mir Arbeit gespart. (Ich fauler Hund, nimm's mir nicht übel...)
Sicher kann man da 2,3 Funktionen schreiben, reduziert das ganze auf wenige Zeilen in den Views oder in Forms, die wohl trotzdem alle geändert werden müssten, wenn sich die Funktion ändert, bsp.-weise ein Argument mehr, oder? Sowas ist absolut machbar, will ich nicht bestreiten, aber auch anfällig. Ich weiss dann immer, wo ich vor Monaten was gemacht hab, was ich mittlerweile schon wieder vergessen hab. Eigentlich benutz ich ja Django, um genau von sowas wegzukommen... By the way, I know "def clean", man...
Noch was: Django-Timezones bringt zwar ein TimeZoneField mit, aber das ist nur in Englisch. Wer sich das anschaut, der kann sich Gedanken über eine Übersetzung ins Deutsche machen.
Und Django-Timezones vom SVN ist z.Zt. strange (kaputt?), siehe
http://code.google.com/p/django-timezon ... tail?id=14
Comment 2 is von mir..
- jens
- Python-Forum Veteran
- Beiträge: 8502
- Registriert: Dienstag 10. August 2004, 09:40
- Wohnort: duisburg
- Kontaktdaten:
Das mit der Zeitzone interessiert mich nun auch ein wenig... Denn die Zeiten sind auf meiner Webseite falsch 
Bei meinem Blog nutzte ich teilweise den template Filter "timesince"...
Aber wie kann man es richtig machen?
Eine Möglichkeit wäre es doch, alles in UTC zu speichern und beim Client per JS bzw. jQuery die zeiten zu korrigieren...
Dumm ist allerdings, das django von sich auf kein UTC verwendet, siehe auch:
http://www.python-forum.de/topic-13534.html
http://www.python-forum.de/topic-19956.html
EDIT: Ach, das Problem an "timesince" ist natürlich, das es quasi nicht cacheable ist.
Ich Frage mich warum django z.B. beim DateTimeField mit "auto_now" bzw. "auto_now_add" ein datetime.now() benutzt und kein datetime.utcnow()... Weiß jemand warum???
EDIT2: Hab es mal nachgefragt: http://groups.google.com/group/django-d ... ef33c88bf3

Bei meinem Blog nutzte ich teilweise den template Filter "timesince"...
Aber wie kann man es richtig machen?
Eine Möglichkeit wäre es doch, alles in UTC zu speichern und beim Client per JS bzw. jQuery die zeiten zu korrigieren...
Dumm ist allerdings, das django von sich auf kein UTC verwendet, siehe auch:
http://www.python-forum.de/topic-13534.html
http://www.python-forum.de/topic-19956.html
EDIT: Ach, das Problem an "timesince" ist natürlich, das es quasi nicht cacheable ist.
Ich Frage mich warum django z.B. beim DateTimeField mit "auto_now" bzw. "auto_now_add" ein datetime.now() benutzt und kein datetime.utcnow()... Weiß jemand warum???
EDIT2: Hab es mal nachgefragt: http://groups.google.com/group/django-d ... ef33c88bf3
- jens
- Python-Forum Veteran
- Beiträge: 8502
- Registriert: Dienstag 10. August 2004, 09:40
- Wohnort: duisburg
- Kontaktdaten:
Geht dieser Template Filter auch einfacher (ein großer Teil ist von contrib/syndication/feeds.py):
Code: Alles auswählen
from datetime import datetime, timedelta
def _get_offset():
now = datetime.now()
utcnow = datetime.utcnow()
# Must always subtract smaller time from larger time here.
if utcnow > now:
sign = -1
tzDifference = (utcnow - now)
else:
sign = 1
tzDifference = (now - utcnow)
# Round the timezone offset to the nearest half hour.
tzOffsetMinutes = sign * ((tzDifference.seconds / 60 + 15) / 30) * 30
tzOffset = timedelta(minutes=tzOffsetMinutes)
return tzOffset
_TZ_OFFSET = _get_offset()
def to_utc(value, arg=None):
value = value - _TZ_OFFSET
return value
- jens
- Python-Forum Veteran
- Beiträge: 8502
- Registriert: Dienstag 10. August 2004, 09:40
- Wohnort: duisburg
- Kontaktdaten:
Offensichtlich ist django in der Sache nicht gut durchdacht. Sehr lesenswert: http://code.djangoproject.com/ticket/10587
- mkesper
- User
- Beiträge: 919
- Registriert: Montag 20. November 2006, 15:48
- Wohnort: formerly known as mkallas
- Kontaktdaten:
UN*X macht sowas schon seit 30 Jahren aus dem Grund, dass man sich anderenfalls schwer ins Knie schiessen kann. Genauso wie man Preise immer netto speichert gehören Uhrzeiten immer in UTC abgespeichert.jens hat geschrieben:Eine Möglichkeit wäre es doch, alles in UTC zu speichern und beim Client per JS bzw. jQuery die zeiten zu korrigieren...
- jens
- Python-Forum Veteran
- Beiträge: 8502
- Registriert: Dienstag 10. August 2004, 09:40
- Wohnort: duisburg
- Kontaktdaten:
hab mir ein kleines "timezone info plugin" für PyLucid geschrieben: http://trac.pylucid.net/changeset/2436
Normalerweise sehen die Ausgaben so ähnlich aus:
Wenn man aber settings.TIME_ZONE="" macht, dann sieht das so aus:
Speichert django also Zeiten in UTC, wenn man TIME_ZONE="" setzt?
So sieht es zumindest aus, wenn man datetime.now() und datetime.utcnow() vergleicht.
Wenn das so ist, dann wäre das doch jetzt schon eine gute Lösung, oder nicht???
Normalerweise sehen die Ausgaben so ähnlich aus:
Code: Alles auswählen
server information
settings.TIME_ZONE
America/Chicago
TZ from os.environ
America/Chicago
datetime now
26. Nov. 2009, 10:56
datetime UTC now
26. Nov. 2009, 16:56
datetime to UTC (calculated with PyLucid template filter 'to_utc')
26. Nov. 2009, 16:56
UTC offset
-1 day, 18:00:00
Client information via JavaScript
Current time from JavaScript
Do 26 Nov 2009 17:53:30 CET
JavaScript timezone offset
-1
Code: Alles auswählen
server information
settings.TIME_ZONE
TZ from os.environ
datetime now
26. Nov. 2009, 16:48
datetime UTC now
26. Nov. 2009, 16:48
datetime to UTC (calculated with PyLucid template filter 'to_utc')
26. Nov. 2009, 16:48
UTC offset
0:00:00
Client information via JavaScript
Current time from JavaScript
Do 26 Nov 2009 17:48:54 CET
JavaScript timezone offset
-1
So sieht es zumindest aus, wenn man datetime.now() und datetime.utcnow() vergleicht.
Wenn das so ist, dann wäre das doch jetzt schon eine gute Lösung, oder nicht???
- jens
- Python-Forum Veteran
- Beiträge: 8502
- Registriert: Dienstag 10. August 2004, 09:40
- Wohnort: duisburg
- Kontaktdaten:
Hab mich dazu entschieden settings.TIME_ZONE auf "Europe/London" zu stellen, was Greenwich Mean Time bzw. GMT-0 ist. Das ist expliziter als einfach ein Leeren String zu übergeben 
Django sollte das in den Voreinstellung auch machen. Ist IMHO besser als "America/Chicago".

Django sollte das in den Voreinstellung auch machen. Ist IMHO besser als "America/Chicago".
- mkesper
- User
- Beiträge: 919
- Registriert: Montag 20. November 2006, 15:48
- Wohnort: formerly known as mkallas
- Kontaktdaten:
Keine gute Idee, da Europe/London auch Daylight Saving Times beinhalten kann: http://www.timezoneconverter.com/cgi-bi ... ope/London
- jens
- Python-Forum Veteran
- Beiträge: 8502
- Registriert: Dienstag 10. August 2004, 09:40
- Wohnort: duisburg
- Kontaktdaten:
Oh, stimmt.
Dann doch besser leer lassen? Oder eins davon nehmen:
EDIT: MET und CET (Mitteleuropäische Zeit) fällt schon mal raus, weil es UTC +1h ist: http://de.wikipedia.org/wiki/Mitteleuro ... ische_Zeit
Man könnte aber auch einfach TIME_ZONE = "UTC" nehmen und gut ist
Dann doch besser leer lassen? Oder eins davon nehmen:
- * GMT GMT+0 GMT-0 GMT0 Greenwich Etc/GMT Etc/GMT+0 Etc/GMT-0 Etc/GMT0 Etc/Greenwich
* MET
* CET
EDIT: MET und CET (Mitteleuropäische Zeit) fällt schon mal raus, weil es UTC +1h ist: http://de.wikipedia.org/wiki/Mitteleuro ... ische_Zeit
Man könnte aber auch einfach TIME_ZONE = "UTC" nehmen und gut ist
