【问题标题】:save time zone in Django Models在 Django 模型中保存时区
【发布时间】:2012-03-16 06:54:49
【问题描述】:

我正在 Django 中创建一个表单。我必须放置一个输入类型字段,该字段仅将时区存储在数据库中(用户将从表单的下拉列表中选择)。我无法找到创建此时区模型的任何方法以及它将如何根据保存的时区返回本地时间。我选择以下字段,但它也存储分钟和秒

 timestamp = models.DateTimeField()

下拉列表应采用以下形式: ... 格林威治标准时间 +5:30 GMT +6:00...等等。

【问题讨论】:

    标签: python django django-models timezone


    【解决方案1】:

    如果您要从 pytz 迁移到 zoneinfo

    try:
        import zoneinfo
    except ImportError:
        from backports import zoneinfo
    
    class UserProfile(models.Model):  
        TIMEZONE_CHOICES = ((x, x) for x in sorted(zoneinfo.available_timezones(), key=str.lower))
        timezone = models.CharField("Timezone", choices=TIMEZONE_CHOICES, max_length=250, default='Etc/GMT+2')
    

    【讨论】:

      【解决方案2】:

      我认为上面的答案都是正确的,但我把我的答案留在这里作为一个简单的例子...

      class UserProfile(models.Model):  
      
          import pytz
          TIMEZONES = tuple(zip(pytz.all_timezones, pytz.all_timezones))
      
          # ...
          timezone = models.CharField(max_length=32, choices=TIMEZONES, 
          default='UTC')
      # ...
      

      【讨论】:

      • 官方最大长度 32 ?
      • @cristian len(max(pytz.all_timezones, key=len)) == 32
      • 也可能感兴趣,而不是 pytz.all_timezonespytz.common_timezonespytz.country_timezones('...')。见here
      【解决方案3】:

      我这样做的方法是使用 pytz 有效的时区名称。我调整了我的列表以仅反映我需要的那些,即

      TIMEZONES = (
          'Canada/Atlantic',
          'Canada/Central',
          'Canada/Eastern',
          'Canada/Mountain',
          'Canada/Pacific',
      )
      

      然后我有一个位置类,它将时区设置为一个字符字段:

      class Location(models.Model):
          ....
          time_zone = models.CharField(max_length=100, blank=True, null=True, choices=TIMEZONES)  # 64 min
          ....
      

      请注意,我将空白和 null 设置为 True 以使该字段可选。看看django-timezone-field fields.py 以获得更多想法。

      要在我的 pytz 代码中使用它,我导入时区:

      from pytz import timezone
      import datetime
      from locations.models import Location # my object that has the time_zone field
      loc = Location.objects.get(pk=1)  #get existing location or your object that has time_zone field
      utc = pytz.utc
      some_utc_date = datetime.datetime(2002, 10, 27, 6, 0, 0).replace(tzinfo=utc) #tz aware
      some_date.astimezone(timezone(loc.time_zone))
      

      将 datetime.datetime(2002, 10, 27, 6, 0, 0) 替换为与您的位置或具有 time_zone 字段的特定对象相对应的日期时间字段。就我而言,我将所有日期字段以 UTC 格式存储在 MongoDB 集合中。当我检索数据并想要创建人类可读的输出时,我使用上述方法在输出中显示日期。您还可以创建自定义标签来在模板中处理此问题。有关详细信息,请参阅pytz doc。

      【讨论】:

        【解决方案4】:

        django-timezone-field 是一个可以很好地处理这个问题的应用程序。

        【讨论】:

          【解决方案5】:

          django 和 python 都没有提供一组时区供您使用。

          为此,您将需要一个额外的模块,例如 pytz。您可以像这样获取所有时区的列表:

          >>> import pytz
          >>> pytz.all_timezones ['Africa/Abidjan', 'Africa/Accra', 'Africa/Addis_Ababa', 'Africa/Algiers', 'Africa/Asmara',
          'Africa/Asmera'....
          

          您可以将时区名称存储在CharField 中。

          顺便说一句,通过“GMT +6:00”选择时区并不是一个好主意。例如,EST 通常比 GMT 晚 5 小时,但在夏令时更改前后的 2 周内,偏移量是不同的。此外,在一年中的某些时候,昆士兰州的某个人和新南威尔士州的某个人都有相同的 GMT 偏移量,但由于新南威尔士州有 DST 而昆士兰州没有,因此在半年中他们的 GMT 偏移量是不同的。列出时区的唯一安全方法是列出实际的地理时区。

          【讨论】:

          • 我想在某个地方汇总我的应用程序,所以当他/她运行这个应用程序时,它的运行环境中必须有 pytz?
          • 值得注意的是,从 python 3.9 开始(在这个答案之后的几年发布!)现在完全支持 python 中的时区,使用 zoneinfo 模块... pytz 现在已弃用:)
          猜你喜欢
          • 2023-03-23
          • 2020-01-21
          • 1970-01-01
          • 1970-01-01
          • 2021-12-03
          • 1970-01-01
          • 2021-07-26
          • 2019-03-29
          • 2014-07-19
          相关资源
          最近更新 更多