Django在同一应用程序中的不同时区 [英] Django different timezones in same application

查看:72
本文介绍了Django在同一应用程序中的不同时区的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用请假管理的Django应用程序,其中有来自不同国家的员工。我将创建休假时的时间数据存储到DB中。现在,我希望此插入数据库的日期时间为该特定员工所在位置的当前本地时间。

I am working on a Django application on Leave Management, in which there are employees from different countries. I am storing the data of the time, when the leave is created, into DB. Now, I want this datetime that is being inserted into DB, to be the current local time of the location where that particular employee is working at.

例如,让我们假设X先生在印度工作,Y先生在纽约工作。如果X申请请假,我希望在当地时间创建它(created_at = 印度现在什么时候),而当Y申请请假时,我希望它被创建created_at = 它在纽约的时间。到目前为止,无论我要插入到DB中的什么,它都只是作为UTC时间插入的。如何解决此问题?

For example, let us suppose Mr. X is working at India and Y is working at Newyork. If X applies for a leave, I want it to be created at local time (created_at= what-so-ever time it is in India) and when Y applies for a leave, I want it to be created_at=what-so-ever time it is in Newyork. As of now, whatever I am inserting into DB, it is getting inserted as UTC time only. How to resolve this issue?

我正在尝试实现这样的目标。但这始终是UTC。

I am trying to achieve something like this.. But it is always UTC.

userid = employees.objects.get(emp_id=request.user.username)

if employees.objects.get(emp_id=request.user.username).emp_loc == 'IND':
    tzone=pytz.timezone('Asia/Calcutta')
elif employees.objects.get(emp_id=request.user.username).emp_loc == 'MLA':
    tzone=pytz.timezone('Asia/Manila')
elif employees.objects.get(emp_id=request.user.username).emp_loc == 'MPLS':
    tzone=pytz.timezone('CST6CDT')

 timezone.activate(pytz.timezone(tzone))
 tnow=timezone.localtime(timezone.now())

if request.POST['action'] == 'Save changes':
        new_leave = leave.objects.create(employee=employees.objects.get(emp_id = userid.emp_id), start_date=sdt, end_date=edt, ltype=ltyp, message=des, date_created=tnow)

    new_leave.save()

非常需要帮助..... :(

Badly in need of help..... :(

谢谢.........:)

Thanks in advance......... :)

推荐答案

Django将日期时间信息存储在数据库中的UTC中,在内部使用可识别时区的日期时间对象,并将其以模板和形式转换为最终用户的时区。

Django stores datetime information in UTC in the database, uses time-zone-aware datetime objects internally, and translates them to the end user’s time zone in templates and forms.

您可以将时区设置为日期时间,然后再将其保存到数据库中。
转到您的settings.py,并将USE_TZ设置为False

You can set timezone to your datetime before saving it to database. go to your settings.py and se USE_TZ to False


请阅读更新3部分。

Please read Update 3 section.



    import pytz
    from datetime import datatime

    leave = leave.objects.get(pk=1)
    time_zone = pytz.timezone('America/Bogota') # set timezone here

    # Before save
    leave.start_date = time_zone.localize(datetime.now())
    leave.save()
    leave.start_date
    > datetime.datetime(2020, 6, 17, 11, 50, 25, tzinfo=<DstTzInfo 'America/Bogota' -05-1 day, 19:00:00 STD>)
      # when USE_TZ is False

或者您可以在请假模型中存储员工的时区,并在检索时手动进行转换。

Or you can store timezone of employee in your leave model and convert it on time of retrieval manually.

import pytz

leave = leave.objects.get(pk=1)
time_zone = pytz.timezone(leave.timezone) # set timezone here

# OR on retrieval
leave_start_date = time_zone.localize(leave.start_date) # timezone aware datetime

更新

PostgreSQL后端存储日期时间为带时区的时间戳。实际上,这意味着它会在存储时将日期时间从连接的时区转换为UTC,并在检索时将其从UTC转换为连接的时区。

The PostgreSQL backend stores datetimes as timestamp with time zone. In practice, this means it converts datetimes from the connection’s time zone to UTC on storage, and from UTC to the connection’s time zone on retrieval.


有关更多信息,您可以查看官方文档,在
迁移指南部分下。

更新2

是否使用postgresql无关紧要,如果要保存多个时区,必须设置 USE_TZ = False,

It doesn't matter if you are using postgresql, if want to save multiple timezone you must set USE_TZ = False,

然后按照上述步骤操作并获取本地时区的日期时间

then follow the steps above and get the datetime in the local time zone


PS:这不是最佳做法,请参见: https:// groups .google.com / forum /#!topic / django-developers / zwQju7hbG78

更新3


以前的方法虽然可以澄清但不建议使用

The previous approaches, although they clarify but are not recommended




  1. 保留USE_TZ = True(如果您的Django版本支持它)

  2. 将created_at DateTimeField重命名为utc_created_at



    utc_created_at = models.DateTimeField(.....)




  1. 通过添加3个其他字段来扩展django模型:


    • a DateField local_created_at

    • a TimeField local_created_time

    • 一个CharField created_timezone(一切正常)



local_created_date = models.DateField(blank=True, .....)
local_created_time = models.TimeField(blank=True, .....)
local_timezone = models.models.CharField(verbose_name="time zone", default=settings.TIME_ZONE, max_length=40)




  1. 覆盖模型save()-(这只是一个示例,请检查执行此操作的最佳方法)



def save(self, *args, **kwargs):
    dt = self.utc_created_at
    if dt:
        self.local_created_date = dt.date()
        self.local_create_time = dt.time()
    super().save(*args, **kwargs)




  1. 在您的表单中(请确保在admin.py中使用此表单)



import pytz
TIME_ZONE_CHOICES = [
    (timezone, timezone) for timezone in pytz.common_timezones
]
timezone = forms.ChoiceField(choices=TIME_ZONE_CHOICES)

这篇关于Django在同一应用程序中的不同时区的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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