2013-02-02 13 views
17

Ho un valore mysql DATETIME archiviato nell'ora di sistema, UTC. Devo convertirlo nel mio fuso orario locale in django. Ecco quello che ho attualmente:Ottieni fuso orario locale in django

# value in mysql 
`timestamp` 
2013-02-01 22:48:45 

# settings.py 
TIME_ZONE = 'America/Los_Angeles' 

# views.py 
last_updated = PathLastUpdated.objects.all()[0].timestamp 
print last_updated 
2013-02-01 22:48:45 <-- same as UTC 

Come dovrei ottenere il valore LAST_UPDATED di essere nel mio locale fuso orario = "America/Los Angeles"?

+0

Per "il mio fuso orario locale" Vuoi dire il fuso orario il server viene eseguito o il fuso orario del client che visualizza la pagina? – Sergey

+0

Il fuso orario che ho impostato in 'settings.py' = 'America/Los_Angeles' – David542

risposta

20

Il Django documentation for timezones documenta tutti i dettagli necessari per convertire gli oggetti datetime nel fuso orario appropriato per la visualizzazione.

I dati vengono memorizzati in UTC che è buono. Quando si ottiene un oggetto campo DateTime dal database, si tratterà di un ingenuo oggetto datetime.datetime. cioè una data/ora senza fuso orario allegato. Spetta a te fare la conversione.

L'utente della tua webapp può trovarsi in fusi orari diversi, pertanto la conversione in un fuso orario appropriato deve avvenire per per ogni richiesta. Questo è il motivo per cui esiste una funzione activate per impostare il fuso orario corrente.

Se avete pytz installato si dovrebbe essere in grado di effettuare le seguenti operazioni:

from django.utils.timezone import activate 
activate(settings.TIME_ZONE) 

Tutto l'output di campo data nel motore di template vi si poi convertire automaticamente gli oggetti Ora Data ingenui per il fuso orario corretto per la visualizzazione .

Se si dispone di un'unica istanza di tipo datetime.datetime su cui si desidera impostare il fuso orario, utilizzare direttamente il modulo pytz. Tuttavia, non è normale farlo nelle visualizzazioni, poiché è consigliabile convertire solo il fuso orario al momento della presentazione.

from pytz import timezone 

settingstime_zone = timezone(settings.TIME_ZONE) 
last_updated = last_updated.astimezone(settings_time_zone) 
+2

se 'last_updated' non è in utc quindi cambia l'ultima riga in:' last_updated_in_tz = tz.normalize (last_updated.astimezone (tz)) '. se 'last_updated' è un oggetto datetime ingenuo, rendilo consapevole prima di chiamare' .astimezone() ':' aware_dt = naive_utc_dt.replace (tzinfo = pytz.utc) '(nota:' .replace() 'funziona solo per utc, usa 'aware_dt = some_tz.localize (naive_dt, is_dst = None)' altrimenti). – jfs

+0

facendo "activate (settings.TIME_ZONE)" si verifica che le impostazioni non sono definite. Ho definito il mio TIME_ZONE = 'UTC' su settings.py. Dove suppongo di definire TIME_ZONE? – ePascoal

+1

@MrMartin Dovrai importare il modulo delle impostazioni di Django come per https://docs.djangoproject.com/en/1.8/topics/settings/#using-settings-in-python-code –

2

io personalmente consiglio di non usare un TIME_ZONE un'impostazione diversa da UTC. Ricordo di aver avuto problemi con questo in passato, che il database stesse operando in un fuso orario diverso (risparmiando valori in un fuso orario diverso) rispetto a quello che il backend Django stava usando. Ciò significava molto fastidio confrontare i tempi, cambiandoli avanti e indietro a seconda di ciò che stai facendo.

Una buona pratica è di solito utilizzare un fuso orario nel back-end (diciamo UTC) e convertire il tempo nel frontend al fuso orario degli utenti che stai servendo.

+0

Sono d'accordo con te. Ho anche problemi con altri fusi orari. Ma quando invio la data dal browser non viene convertita in UTC, puoi suggerirmi un modo corretto? – MegaBytes

+1

Avrei bisogno di più informazioni su come inviare la data dal browser (il formato sarebbe importante, ci sono informazioni sul fuso orario salvate in questo formato).Se la data viene inviata dal browser, devi convertirla in UTC usando Django. Suggerirei una libreria come https://labix.org/python-dateutil per fare questo. –

+0

Grazie per la risposta, il problema ora è risolto ma non so se sia corretto o meno, perché sono nuovo in Django e Python. Attualmente sto facendo in questo modo. Prendo la data e l'ora da jQuery-datepicker e la conversione in ora UTC utilizzando Javascript, e invia al server. Avevo provato con lib di pytz ma c'era un problema con l'identificazione da quale fuso orario veniva la data-ora. che stava creando problemi per convertire in UTC. Non so se ho ragione o torto, per favore suggerisci quale sarà l'approccio giusto da fare. – MegaBytes

5

ho creato un semplice middleware per gestire tutte queste cose per voi:

https://github.com/Miserlou/django-easy-timezones

Basta installarlo e seguire le istruzioni e il gioco è fatto!

  1. Installare django-facile-fusi orari

    pip install django-easy-timezones pytz pygeoip 
    
  2. Aggiungi "Easy-fusi orari" ai tuoi INSTALLED_APPS ambiente come questo:

    INSTALLED_APPS = (
    ... 
    'easy-timezones', 
    ) 
    
  3. Aggiungi EasyTimezoneMiddleware ai tuoi MIDDLEWARE_CLASSES

    MIDDLEWARE_CLASSES = (
    ... 
    'easy-timezones.middleware.EasyTimezoneMiddleware', 
    ) 
    
  4. aggiungere un percorso alla MaxMind GeoIP database nel file impostazioni:

    GEOIP_DATABASE = '/path/to/your/geoip/database/GeoIP.dat' 
    
  5. Abilita localtime nei vostri modelli.

    {% load tz %} 
        The UTC time is {{ object.date }} 
    {% localtime on %} 
        The local time is {{ object.date }} 
    {% endlocaltime %} 
    
  6. Tada!

+0

In base alla tua risposta, ho impostato il fuso orario facile nella mia app django, ma se vuoi eseguire la mia app dal terminale ricevo un errore che dice "nessun modulo ha nominato easy_timezones" sebbene abbia installato il pacchetto usando pip. @Rich Jones – RTan

+0

INSTALLED_APPS e MIDDLEWARE_CLASSES dovrebbero usare "easy_timezones", non "easy-timezones" - è corretto nel tuo readme, ma non in questa risposta. – Spooner

+0

@Rich Jones Come implementarlo se sto usando DRF e angularJS per front-end? Fondamentalmente non sto usando il template Django. Utilizzo di DRF, Postgres, Django1.8 sul lato server e AngularJS/HTML sul lato front-end. – Amar

13

Dopo piangere molto, ho potuto mostrare la data corretta per il mio Paese a fare qualcosa di simile:

>>> from django.utils.timezone import get_current_timezone 
>>> from front.models import Training 

>>> tz = get_current_timezone() 
>>> stored_date = Training.objects.first().start_date 
datetime.datetime(2015, 4, 25, 17, 0, tzinfo=<UTC>) 

>>> desired_date = stored_date + tz.utcoffset(stored_date) 
datetime.datetime(2015, 4, 25, 14, 0, tzinfo=<UTC>) 

L'attributo tzinfo è mostra UTC, ma la data e l'ora è corretto mostrare.

AGGIORNAMENTO 30/10/2015 (Django 1.8)

sto utilizzando un altro approccio di oggi, che è più amichevole Django

>>> from django.utils import timezone 
>>> from trainings.models import Training 
>>> value = Training.objects.first().date 

>>> value 
datetime.datetime(2015, 10, 23, 11, 32, 54, 633151, tzinfo=<UTC>) 

>>> timezone.localtime(value) 
datetime.datetime(2015, 10, 23, 9, 32, 54, 633151, tzinfo=<django.utils.timezone.LocalTimezone object at 0x7fa6129784a8>) 
2

ho venuto allo stesso problema. Nelle mie impostazioni, ho impostato TIME_ZONE, ma l'ora in MySql è ancora UTC.

# settings.py 
TIME_ZONE = 'Asia/Shanghai' 

poi ho trovato, in settings.py, USE_TZ deve essere impostato su False

USE_TZ = False

0

Basta usare

timezone.localtime(arg) 
Problemi correlati