1

我有一个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 点时,东海岸的时间会发生变化,所以如果我在太平洋标准时间运行 hit/summary/2013/10并且如果它对Oct 21 2013我来说是在太平洋标准时间,则日期在美国东部标准时间已经改变,所以days_left: 8这在客户端是不正确的。正确的?

我该如何处理这种情况?

4

2 回答 2

4

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

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

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

如果您确实需要处理其他时区(例如,为了向用户显示),您可能需要使用外部库,因为 python 本身不提供时区数据库。这个问题有更多关于这方面的信息。

于 2013-10-21T16:22:16.243 回答
1

你有几个选择。

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

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

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

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

于 2013-10-21T16:22:58.140 回答