如何处理来自不同时区的数据时间 [英] How to handle datetimes from different timezones

查看:183
本文介绍了如何处理来自不同时区的数据时间的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个django应用程序,它存储在数据库(postgres)数据时间在UTC,它有全球用户。

I have a django application and it stores in the database (postgres) the datetimes in UTC, it has users worldwide.

但在应用程序逻辑中,我有一些根据当地时间范围的验证,即用户在瓜亚基尔,有些事情发生在所有的星期天;我有问题要执行它,并做一些调试,我发现在UTC在星期一凌晨2点,但用户(美洲/瓜亚基尔)UTC-5仍在星期二21:00。因此,由于DAY发生变化,因此用户失败。

But in the application logic, I have some validations according to local time ranges, i.e. the user is on Guayaquil and some thing happens all sunday; I'm having issues to perform it and doing some debugging I found that in UTC is monday at 2AM at but the user (America/Guayaquil) UTC-5 is still on sunday 21:00. So it fails for the user because the DAY changed.

我正在考虑将用户时区存储在用户表中,但我不知道如何设置它,以及如何为了防止以前的情况。

I am thinking of storing the user timezone in the user table but I don't know how to set it and how to prevent the previous scenario.

作为一个侧面的问题,如何将存储在数据库中的UTC datetime转换为用户的时区(例如)电子邮件通知。 (我不会给他发送一封电子邮件,带有日期时间和时区,让他在脑海里做数学)。

As a side question, how can I convert a UTC datetime stored in the database to the user's timezone for (example) email notification. (I'm not going to send him an email with datetime and timezone for him to do the math in his mind).

推荐答案

这是很好的,你存储的所有东西在 UTC 。现在您不需要将用户时区存储在数据库中,您可以做的是在登录页面上,您可以从 UTC 中计算用户偏移量并存储在会话vi ajax中。以下是您可以在登录页面模板中添加的简单脚本:

That is good you are storing everything in UTC. Now you don't need to store the user timezone in database what you can do is that on login page you can calculate the user offset from UTC and store in session vi ajax. Here is the simple script you can include in your login page template:

<script>
    $(document).ready(function(){
        var visitortime = new Date();
        var visitortimezone = - visitortime.getTimezoneOffset()/60;

        $.ajax({
            type: "POST",
            url: "{% url 'update_timezone' %}",
            data: {'time_zone': visitortimezone, 'csrfmiddlewaretoken': '{{csrf_token}}'},
            dataType: "text"
        });
    });
</script>

在您的根目录中添加此url urls.py:

Add this url in your root urls.py:

url(r'^update_timezone/$',
    'MySite.views.update_timezone',
    name='update_timezone'),

添加此视图:

def update_timezone(request):
    time_zone = request.POST.get('time_zone', 0)
    if time_zone:
        request.session['user_timezone_offset'] = float(time_zone)*60*60
    return HttpResponse(
        simplejson.dumps({}), mimetype='application/javascript')

现在您在会话中使用时区偏移。现在来计算的部分。你需要这两个简单的帮助函数:

Now you have user timezone offset in session. Now comes the part for calculation. You need these two simple helper functions:

from datetime import timedelta

def add_user_offset(dt, offset):
    if offset:
        dt = dt + timedelta(seconds=offset)
    return dt


def subtract_user_offset(dt, offset):
    if offset:
        dt = dt - timedelta(seconds=offset)
    return dt

如果您想根据自己的时区显示用户时间,请执行以下操作:

Ok if you want to show the user time according to the his/her timezone you would do:

created = add_user_offset(obj.created, request.session.get('user_timezone_offset'))

如果你有日期时间或日期来自表单,并且您想要验证它,例如选择的日期不应小于您将要执行的当前日期:

If you have datetime or date coming from the form and you want to validate it e.g. the date chosen should not be less than current date you would do:

from django.utils import timezone

d = request.POST['date']
d_normalize = subtract_user_offset(d, request.session.get('user_timezone_offset'))
if d_normalize < timezone.now():
    raise Exception, 'Date must be in future'

这种方法的好处是您不需要要求用户指定他们的时区。我们正在自动地做所有事情。

The benefit of this approach is that you don't need to ask users to specify their timezones. We are doing everything automatically on our side.

这篇关于如何处理来自不同时区的数据时间的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆