【问题标题】:Working with several time zone in Django在 Django 中使用多个时区
【发布时间】:2015-09-03 17:28:25
【问题描述】:

我正在开发的应用程序的目标用户是美国。而且(您可能知道)在美国有不止一个时区。所以我有一些疑问:

  • 那么如何根据 当前用户?
  • 我如何存储DateTime 数据以显示正确的时间 每个用户?
  • 如何比较时间(例如:user.event.created > datetime.now())? .now() 将使用哪个时区?
  • 我应该在settings.py 文件中设置什么TIME_ZONE。

这是一个 API,不能通过 JS 获取用户的时区。我通过 TokenAuthentication 获取当前用户。

【问题讨论】:

    标签: python django internationalization django-timezone


    【解决方案1】:

    UTC 用于settings.py 并从Javascript 中获取它们的时区偏移:

    var utcOffset = -((new Date()).getTimezoneOffset()) / 60;
    

    例如现在去洛杉矶utcOffset == -7

    不幸的是,这并没有考虑到稍后的夏令时更改(偏移更改为-8),因此您可能必须在检索时弄清楚这一点才能获得Pacific/Los_Angeles。否则,您总是可以在注册表单中询问用户这对您的业务是否重要。

    编辑:由于您使用的是 API,您还可以尝试使用 IPInfoDB API 根据客户端 IP 地址进行地理定位。它并不总是完全准确,但几乎总是足以获得正确的时区。

    【讨论】:

    • 感谢您的回答,我可能需要询问用户。我必须指出答案我正在使用 API,所以我不能使用 JS 来获取用户的时区。
    • @Gocht 我用另一种可能的解决方案编辑了我的答案,因为您使用的是 API。
    • 所以你推荐存储用户时区?或者每次用户访问 API 时获取它。我带着更多疑问编辑了这个问题。
    • 你需要根据你的商业模式自己弄清楚。我参与了一个存储时区的项目,因为我们需要创建图表和数据表并确保它们保持一致。我可以看到您每次都想收集它的用例(尽管我会回避这个),但我不了解您的业务。
    • 请告诉你一点。我有用户type1type2,用户type1 创建events,用户type2 必须在他们的位置区域(基于地图)看到事件。目前我使用auto_now 存储自动created,但它存储服务器的`now`,但用户可以设置event_date,现在我需要对事件通过其日期做一些事情,这就是我需要比较时间的原因。用户将根据他的时区设置event_date,这可能与服务器时区不同,甚至用户type2用户
    【解决方案2】:

    不要使用 datetime.now(),而是使用 timezone 模块中的 now() 函数。

    from django.utils import timezone
    
    now = timezone.now()
    

    Django 会找出你所在的时区并相应地进行比较。

    user.event.created > timezone.now()
    

    https://docs.djangoproject.com/en/1.8/topics/i18n/timezones/

    【讨论】:

    • 我猜timezone.now()settings.py 文件中获取时区。但在某些情况下,用户会有不同的时区。
    • 默认情况下它使用设置中的时区,但如果您有用户特定的时区,您可以激活 timezone.activate(pytz.timezone(tzname))。查看上面链接中的 TimezoneMiddleware。
    【解决方案3】:

    解决方案是始终将 unix 时间戳存储在数据库中。您可以使用 time.time() 生成。这意味着您的模型应该有一个 Floatfield(甚至是 BigIntegerField,具体取决于所需的精度)。

    您的模板应按原样显示数值。然后,您需要一点点 javascript 来将该 unix 时间戳转换为日期时间。

    new Date(unix_timestamp);
    

    【讨论】:

      【解决方案4】:

      您的 webapp 的用户可能处于不同的时区,因此需要转换到适当的时区。您可以创建一个中间件并使用activate 函数来设置适当的时区。您可以通过在登录页面中对 Free IP Geolocation API 进行 ajax api 调用来获取客户端时区,并且时区值可以保存在 cookie 变量中,以后可以在中间件中访问该变量。

      landingpage.html

      <script>
      $.ajax({
              url: 'https://freegeoip.app/json/',
              dataType: 'json',
              success: function (data) {
                  document.cookie = 'timezone=' + data['time_zone'] + '; path=/';
              }
            });
      </script>
      

      middleware.py

      import pytz
      import requests
      
      from django.utils import timezone
      
      class TimezoneMiddleware:
          def __init__(self, get_response):
              self.get_response = get_response
      
      def __call__(self, request):
          
          tzname = request.COOKIES.get('timezone')
          if tzname:
              timezone.activate(pytz.timezone(tzname))
          else:
              timezone.deactivate()
          return self.get_response(request)
      

      settings.py

      MIDDLEWARE = [      ........
                  'projectname.middleware.TimezoneMiddleware',
      

      ]

      【讨论】:

        猜你喜欢
        • 2022-01-03
        • 2014-11-28
        • 2021-08-08
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-12-12
        • 2017-10-20
        相关资源
        最近更新 更多