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



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

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

但是,我需要在 Python 中将 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'
})

因此,即使当前时间以 EST 时间(我的本地时区)April 14, 2012, 5:52 p.m.,JSON 响应也会返回 April 14, 2012, 9:52 p.m ,因为那是 UTC 时间。

我还注意到 Django 为每个请求存储一个名为 TIME_ZONE 的模板变量(实际上不是 request 变量的一部分),所以既然 my 是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()

有没有办法将datetime转换为 UTC 以外的其他内容?例如,我可以做类似 current_time = timezone.now() 、然后current_time.replace(tzinfo=est)(EST = 东部标准时间)之类的操作吗?

你需要仔细阅读 Django 时区文档。

重要的一点:

没有等效的接受语言HTTP头,Django可以用来自动确定用户的时区。

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

您还需要确保:

USE_TZ = True

在你的settings.py.

获得时区tz后,您可以:

from django.utils import timezone
timezone.activate(tz)
datetime = timezone.now() if checked else None

获取时区感知datetime对象 时区 tz

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

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

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

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

由于您想要用户的时区,因此这应该在使用 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>

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

相关文档:

  • Javascript Date 类(特别是接受日期字符串的构造函数和 toLocaleFormat() 方法)

  • strftime(带有许多日期格式快捷方式)

相关内容

  • 没有找到相关文章

最新更新