如何获取访问者的当前时区,然后将timezone.now()转换为Django 1.4中的本地时间字符串?

hob*_*es3 6 python django timezone

我知道现在使用Django 1.4的最佳做法是将所有内容存储datetime在UTC中并且我同意这一点.我也明白所有时区对话都应该在模板级别完成,如下所示:

{% load tz %}

{% timezone "Europe/Paris" %}
    Paris time: {{ value }}
{% endtimezone %}
Run Code Online (Sandbox Code Playgroud)

但是,我需要在UTC中将UTC时间转换为request本地时间.我不能使用模板标签,因为我使用Ajax(更具体地说是Dajaxice)在JSON中返回字符串.

目前这是我的代码ajax.py:

# 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'
})
Run Code Online (Sandbox Code Playgroud)

因此,即使当前时间是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头)?

无论如何,所以我的问题是双重的:

  1. 如何获取访客的本地时区ajax.py?(可能会将其作为字符串参数传递{{ TIME_ZONE }})
  2. 使用访问者的本地时区,如何将UTC转换timezone.now()为本地时区并使用Django输出为字符串dateformat

编辑:为@agf

timezone.now()给出UTC时间USE_TZ = True:

# 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()
Run Code Online (Sandbox Code Playgroud)

无论如何将转换为datetimeUTC以外的东西?例如,我可以这样做current_time = timezone.now(),那么current_time.replace(tzinfo=est)(EST =东部标准时间)?

agf*_*agf 10

您需要仔细阅读Django Timezones文档.

一点很重要:

没有相当于Django可以用来自动确定用户时区的Accept-Language HTTP标头.

您必须询问用户他们的时区是什么,或者只是使用默认值.

您还需要确保:

USE_TZ = True
Run Code Online (Sandbox Code Playgroud)

在你的settings.py.

有了时区后tz,您可以:

from django.utils import timezone

timezone.activate(tz)

datetime = timezone.now() if checked else None
Run Code Online (Sandbox Code Playgroud)

datetime在时区中获取时区感知对象tz.


tyl*_*erl 6

虽然浏览器不会向服务器发送指示时区的任何标头,但JavaScript环境确实知道其当前时区.

这有两个重要的影响:虽然服务器无法在初始请求中找到您当前的时区,但您可以发送一些javascript代码来确定TZ偏移并将该信息发送回服务器,以便区域信息可以是从那时起与当前会话相关联.

但更重要的是,如果您在JSON数据中发送时间值,这将由浏览器客户端解释,则不需要知道浏览器的时区.相反,您只需要确保JSON输出中存在时区偏移量,以便浏览器可以在事后进行自己的时区数学运算.

var now = new Date()
var offset_minutes = now.getTimezoneOffset()  # e.g. 240 for GMT-0400
Run Code Online (Sandbox Code Playgroud)