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

2024-04-26 03:32:34 发布

您现在位置:Python中文网/ 问答频道 /正文

我知道Django 1.4现在的最佳实践是将所有datetime存储在UTC中,我同意这一点。我还知道,所有时区对话都应该在模板级别进行,如下所示:

{% load tz %}

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

但是,我需要用Python将UTC时间转换为request的本地时间。我不能使用模板标记,因为我使用Ajax返回JSON格式的字符串(更具体地说是Dajaxice)。

目前这是我的代码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'
})

因此,即使当前时间在EST time(我的本地时区)中是April 14, 2012, 5:52 p.m.,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()给出当USE_TZ = True时的UTC时间:

# 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()

还有什么可以将datetime转换成UTC以外的内容吗?例如,我可以做一些类似于current_time = timezone.now(),然后current_time.replace(tzinfo=est)(EST=东部标准时间)的事情吗?


Tags: django字符串模板datetimeiftimeis时间
3条回答

虽然浏览器不向服务器发送任何表示时区的头,但是JavaScript环境知道其当前时区。

这有两个重要的影响:当服务器在初始请求中找不到您当前的时区时,您可以向下发送一些javascript代码,这些代码将确定TZ偏移量并将该信息发送回服务器,以便区域信息可以从此点向前与当前会话关联。

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

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

你需要仔细阅读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对象。

因为您需要用户的时区,所以我觉得应该在浏览器上使用Javascript来完成这项工作。

我将类似的内容传递到模板中:

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

其中obj是django模型的实例,其中timestamp字段的类型为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>

对我来说,这输出如下:2/15/2017,05:22:24 PM(PST)

相关文件:

相关问题 更多 >