Вопрос по python, timezone – Как получить текущий часовой пояс посетителя, а затем преобразовать timezone.now () в строку местного времени в Django 1.4?

6

Я понимаю, что теперь лучшая практика с Django 1.4 - хранить всеdatetime в UTC и я с этим согласен. Я также понимаю, что все разговоры о часовых поясах должны проводиться на уровне шаблона следующим образом:

<code>{% load tz %}

{% timezone "Europe/Paris" %}
    Paris time: {{ value }}
{% endtimezone %}
</code>

Однако мне нужно преобразовать время UTC вrequestпо местному времени в Python. Я не могу использовать теги шаблона, так как я возвращаю строку в JSON, используя Ajax (более конкретноDajaxice).

В настоящее время это мой кодajax.py:

<code># checked is from the checkbox's this.value (Javascript).
datetime = timezone.now() if checked else None

$ order_pk is sent to the Ajax function.
order = Order.objects.get(pk=order_pk)
order.time = datetime
order.save()

return simplejson.dumps({
    'error': False,
    'datetime': dateformat.format(datetime, 'F j, Y, P') if checked else 'None'
})
</code>

Так что даже если текущее времяApril 14, 2012, 5:52 p.m. во время EST (мой местный часовой пояс) ответ JSON вернетсяApril 14, 2012, 9:52 p.m, потому что это время UTC.

Также я заметил, что Django хранит переменную шаблона с именемTIME_ZONE для каждого запроса (на самом деле не является частьюrequest переменная), так как мойAmerica/New_YorkЯ предполагаю, что Django может выяснить собственный часовой пояс каждого посетителя (на основе заголовка HTTP)?

В любом случае, поэтому мой вопрос двоякий:

How do I get the visitor's local timezone in my ajax.py? (Probably pass it as a string argument like {{ TIME_ZONE }}) With the visitor's local timezone, how to convert the UTC timezone.now() to the local timezone and output as a string using Django's dateformat?

EDIT: для @agf

timezone.now() дает время UTC, когдаUSE_TZ = True:

<code># From django.utils.timezone
def now():
    """
    Returns an aware or naive datetime.datetime, depending on settings.USE_TZ.
    """
    if settings.USE_TZ:
        # timeit shows that datetime.now(tz=utc) is 24% slower
        return datetime.utcnow().replace(tzinfo=utc)
    else:
        return datetime.now()
</code>

Есть ли в любом случае конвертироватьdatetime к чему-то кроме UTC? Например, могу ли я сделать что-то вродеcurrent_time = timezone.now(), затемcurrent_time.replace(tzinfo=est) (EST = восточное стандартное время)?

Ваш Ответ

3   ответа
6

Хотя браузер не отправляет на сервер заголовки, которые бы указывали часовой пояс, среда JavaScriptdoes знать его текущий часовой пояс.

Это имеет два важных эффекта: хотя сервер не может определить ваш текущий часовой пояс по первоначальному запросу, выcan отправьте некоторый код JavaScript, который определит смещение TZ, и отправьте эту информацию обратно на сервер, чтобы информация о зоне могла быть связана с текущим сеансом с этого момента.

Но что более важно, если вы отправляете свое значение времени внутри данных JSON, которые будут интерпретироваться клиентской стороной браузера, часовой пояс браузера не будетneed быть известным. Вместо этого вам нужно только убедиться, что в выходных данных JSON присутствует смещение часового пояса, чтобы браузер мог после этого выполнять собственную математику часового пояса.

var now = new Date()
var offset_minutes = now.getTimezoneOffset()  # e.g. 240 for GMT-0400
1

Поскольку вы хотите, чтобы пользователи & apos; часовые пояса, это имеет смысл для меня, что это должно быть сделано в браузере с Javascript.

Я передаю что-то вроде этого в шаблон:

{"t": str(obj.timestamp))

Где obj - это экземпляр модели django, где поле отметки времени имеет тип DateTimeField.

Шаблон:

<div class="timestring">{{ t }}</div> 
...
<script>
  $('.timestring').each(function(){
    var d = new Date($(this).text());
    $(this).text(d.toLocaleDateString() + ", " + d.toLocaleFormat("%r (%Z)"));
  })
</script>

Для меня это выводит что-то вроде: 15.02.2017, 17:22:24 (PST)

Соответствующая документация:

10

Вам нужно прочитатьDjango Timezones docs внимательно.

Один важный момент:

there's no equivalent of the Accept-Language HTTP header that Django could use to determine the user's time zone automatically.

Вы должны спросить пользователя, какой у него часовой пояс, или просто использовать значение по умолчанию.

Вы также должны убедиться:

USE_TZ = True

в вашемsettings.py.

Когда у вас есть часовой поясtz, вы можете:

from django.utils import timezone

timezone.activate(tz)

datetime = timezone.now() if checked else None

чтобы получить информацию о часовом поясеdatetime объект в часовом поясеtz.

Error: User Rate Limit Exceededtimezone.now() доtimezone.activate(tz)Error: User Rate Limit ExceededorderError: User Rate Limit Exceededdatetime. hobbes3
Error: User Rate Limit Exceededsomedatetime.replace(tz=sometz).
Error: User Rate Limit Exceeded
Error: User Rate Limit ExceededdatetimeError: User Rate Limit Exceededreplace(tz=thetz)Error: User Rate Limit Exceededtimezone.now()Error: User Rate Limit Exceeded
Error: User Rate Limit Exceededcurrent_time = timezone.now()прикрепи это кorderError: User Rate Limit Exceededcurrent_timeError: User Rate Limit Exceeded hobbes3

Похожие вопросы