po5*_*o5i 1 django timezone datetime
我有一个django应用程序,它在数据库(postgres)中存储UTC的日期时间,它在全球范围内拥有用户.
但是在应用程序逻辑中,我根据当地时间范围进行了一些验证,即用户在瓜亚基尔,有些事情在星期天发生; 我有问题要执行它并做一些调试我发现在UTC是星期一凌晨2点,但用户(美国/瓜亚基尔)UTC-5仍然在星期天21:00.所以它对用户来说是失败的,因为DAY已经改变了.
我正在考虑将用户时区存储在用户表中,但我不知道如何设置它以及如何防止以前的情况.
作为一个附带问题,如何将存储在数据库中的UTC日期时间转换为(示例)电子邮件通知的用户时区.(我不打算给他发一封日期时间和时区的电子邮件,让他在脑海里做数学计算).
你把所有东西存放在里面都很好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>
Run Code Online (Sandbox Code Playgroud)
在您的根urls.py中添加此网址:
url(r'^update_timezone/$',
'MySite.views.update_timezone',
name='update_timezone'),
Run Code Online (Sandbox Code Playgroud)
添加此视图:
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')
Run Code Online (Sandbox Code Playgroud)
现在,您在会话中有用户时区偏移量.现在是计算的部分.你需要这两个简单的辅助函数:
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
Run Code Online (Sandbox Code Playgroud)
好的,如果你想根据他/她的时区显示用户时间你会这样做:
created = add_user_offset(obj.created, request.session.get('user_timezone_offset'))
Run Code Online (Sandbox Code Playgroud)
如果您有来自表单的日期时间或日期,并且您想验证它,例如,所选日期不应小于您当前的日期:
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'
Run Code Online (Sandbox Code Playgroud)
这种方法的好处是您不需要要求用户指定他们的时区.我们正在自动做所有事情.