【问题标题】:How to handle date difference between client and server?如何处理客户端和服务器之间的日期差异?
【发布时间】:2013-10-30 05:16:40
【问题描述】:

我有一个API,看起来像

/summary/yyyy/mm
  • 返回请求的年份和月份的数据摘要。
  • 如果这是当前年份和月份,它会返回剩余天数。例如:days_left: 9 代表 201310,服务器上的当前日期是 21 Oct 2013

我如何计算剩余天数?
这是在python中实现的

def current_financial_month_details(self):
        time_from, time_to = self \
            .get_start_end_time_current_financial_month()

        today = datetime.today()
        from_time = datetime(year=today.year, month=today.month,
                             day=today.day)
        return {
            'time_from': time_from,
            'time_to': time_to,
            'remaining_days': (time_to - from_time).days
        }

问题?

  • 服务器在东海岸,客户端(我用浏览器)在太平洋时区
  • 当太平洋标准时间晚上 9 点时,东海岸的时间会发生变化,所以如果我在 PST 上运行 /summary/2013/10 并且如果它是 Oct 21 2013 对我来说,则日期在美国东部标准时间已经改变,所以 days_left: 8 不正确客户端。对吗?

我该如何处理这种情况?

【问题讨论】:

  • 向您的 API 添加时区参数?
  • 很大程度上取决于你要做什么。如果它是分布式用户使用的某种时空分布式数据 - 您最好在 UTC 中工作并要求所有客户端进行转换/需要时区参数并立即在服务器上转换为 UTC(在达到业务逻辑之前)

标签: python date timezone


【解决方案1】:

大多数人认为最佳做法是将日期和时间存储在独立于地理位置的时区(最常见的是 UTC)中。如果您的服务将从具有不同时区的位置访问(或可能最终访问),这同样适用。

正如 J0HN 所提到的,客户端在与服务器交互时应负责从/转换为 UTC。在您的情况下,这意味着 days_left 应定义为当前 UTC 日期和月底(以 UTC 表示)之间的天数。

特别是对于 python,有两种类型的 datetime.datetime 对象:naive and timezone-aware。朴素的日期时间不附加任何时区信息,因此(在网络程序中)一个好的做法是只对 UTC 时区的时间使用朴素的日期时间。要进行计算(例如减去两个日期),请考虑使用datetime.utcnow 而不是datetime.now,这样可以避免任何与时区相关的问题,包括(但不限于)由DST 引起的错误时间增量。

如果您真的需要处理其他时区(例如,为了向用户显示),您可能需要使用外部库,因为 python 本身不提供时区数据库. This question 有更多相关信息。

【讨论】:

    【解决方案2】:

    你有几个选择。

    首先是指定交付结果的时区,并希望客户能够忍受这种差异。显而易见的选择是服务器时区或 UTC。

    第二个是让 API 也返回当前日期以及天数。它不会改变结果,但至少您将能够检测到日期与您预期的日期不同。

    第三是让 API 接受时区输入,以便服务器可以调整其处理。

    第四是在午夜以外的某个时间更改日期,例如凌晨 5 点。这仅适用于您的客户都在相似的时区并且您的活动不是全天候的;如果您在中国有客户,您可能会后悔这个选择。

    【讨论】:

    • 我不喜欢API 应该包含这些信息。相反,我想从 HTTP 请求中提取时间,更改服务器上的 UTC,并以天数计算与服务器的 datetime.utcnow() 的差异。这样,API 仍然是完整的,客户端不必担心发送 TZ 信息。你觉得这听起来如何?
    • 我的数据库仅以 UTC 格式保存时间。类似2013-10-13 18:05:05.779-07
    猜你喜欢
    • 1970-01-01
    • 2016-05-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-08-10
    • 1970-01-01
    • 2011-04-06
    • 1970-01-01
    相关资源
    最近更新 更多