2013-07-15 51 views
1

我有一个django应用程序,它以UTC存储数据库(postgres)日期时间,它具有世界各地的用户。如何处理来自不同时区的日期时间

但是在应用程序逻辑,我有一些验证按照本地时间范围,即用户在瓜亚基尔和一些事情发生所有周日;我有问题要执行它并进行一些调试,我发现UTC在星期一凌晨2点在,但用户(美国/瓜亚基尔)UTC-5仍然在星期日21:00。所以用户因为DAY改变而失败。

我想存储在用户表中的用户时区,但我不知道如何设置它,以及如何防止以前的方案。

作为一个方面的问题,我怎么可以转换存储在数据库中的用户的时区为(例如)电子邮件通知的UTC日期时间。 (我不会给他发送带日期时间和时区的电子邮件,让他在他的脑海中进行数学计算)。

+0

看看http://pytz.sourceforge.net/ –

回答

3

这是一个好你在UTC存储的一切。现在,您不需要将用户时区存储在数据库中,您可以执行的操作是在登录页面上,您可以从UTC计算用户偏移量并存储在会话vi ajax中。下面是一个简单的脚本,您可以在您的登录页面模板:

<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> 

添加的网址,你的根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') 

现在会话中有用户时区偏移量。现在来计算的部分。如果你想根据他/她的时区,你会做向用户显示时间

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 

好:您需要这两个简单的辅助功能

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

如果您有日期时间或日期的到来表单,你想验证它,例如选择应不低于当前的日期,你会做的日期:

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' 

这种方法的好处是,你不需要让用户可以给指定的时区。我们正在自动处理所有事情。

0

默认django是美国/芝加哥时区。您需要在数据库中存储用户时区的最佳方式,以及每当用户登录从DB获取时区并通过代码更改配置时。

import datetime 
from django.utils.timezone import utc 
now = datetime.datetime.utcnow().replace(tzinfo=utc) 

https://docs.djangoproject.com/en/dev/ref/settings/#time-zone

+0

数据已经以UTC保存在数据库中,并且保存用户时区不是问题......主要问题是我写的第二段。 – po5i

1

在Django的全球战略是持久层使用UTC,并使用与最终用户交互时的本地时间(你可以看看here。 因此在您的使用情况下,我会坚持的时间在UTC在DB和使用当前时区处理您所需要的计算

时区选择功能是here 。使用get_current_timezone()可以获得tzinfo对象。

当前时区是用于呈现网页的时区。它可能不是您想要的那个,例如用户是否想要使用UTC-1时区,但当前正在以UTC + 1格式查看网页。在这种情况下,最好让您使用Aamir解释的类似方法将时区保留在会话中,或坚持下去。

模型中的持久化方法仅仅使用CharField并放置可以使用pytz包得到的时区字符串。

相关问题