6

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

{% load tz %}

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

但是,我需要request在 Python 中将 UTC 时间转换为本地时间。我无法使用模板标签,因为我使用 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'
})

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

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

反正有没有将 a 转换为datetimeUTC 以外的东西?例如,我可以执行类似current_time = timezone.now(), then current_time.replace(tzinfo=est)(EST = Eastern Standard Time) 的操作吗?

4

3 回答 3

10

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

重要的一点:

没有与 Django 可以用来自动确定用户时区的 Accept-Language HTTP 标头等效的东西。

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

您还需要确保:

USE_TZ = True

在你的settings.py.

有了 timezonetz后,您可以:

from django.utils import timezone

timezone.activate(tz)

datetime = timezone.now() if checked else None

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

于 2012-04-14T22:23:08.347 回答
6

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

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

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

var now = new Date()
var offset_minutes = now.getTimezoneOffset()  # e.g. 240 for GMT-0400
于 2013-08-09T06:30:12.913 回答
1

既然你想要用户的时区,我觉得这应该在浏览器上使用 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)

相关文件:

于 2017-02-16T01:47:42.853 回答