2

确实非常奇怪的错误。我有一个每个月都会克隆自己的项目,将下一个对象设置为将来有一个scheduled_on日期+ 1.months

但后来发生了这种情况:

Sun, 01 Apr 2012 16:00:00 PDT -07:00
Tue, 01 May 2012 16:00:00 PDT -07:00
Fri, 01 Jun 2012 16:00:00 PDT -07:00
Sun, 01 Jul 2012 16:00:00 PDT -07:00
Wed, 01 Aug 2012 16:00:00 PDT -07:00
Fri, 31 Aug 2012 17:00:00 PDT -07:00 # <--- What in the..

编码 :

def clone_object
  objects = []

  Time.zone = account.timezone
  Chronic.time_class = Time.zone

  now = last_scheduled_on.to_time # <- this would have been Wed, 01 Aug 2012 16:00:00 PDT -07:00

  new_date = now + 1.months

  new_schedule = Time.zone.parse new_date.strftime('%Y-%m-%d' + ' ' + original_scheduled_on.strftime('%H:%M:%S'))

  objects << clone!(:scheduled_on => new_schedule, :recurring_job_id => id)

end

这是实际代码的一个非常截断的版本。但它包括我合理影响这个问题的所有部分。

所以问题是..这个错误怎么可能发生?

更新

我很确定这与时区有关。

以下是 UTC 日期:

In UTC :

Sun, 01 Apr 2012 23:00:00 UTC +00:00
Tue, 01 May 2012 23:00:00 UTC +00:00
Fri, 01 Jun 2012 23:00:00 UTC +00:00
Sun, 01 Jul 2012 23:00:00 UTC +00:00
Wed, 01 Aug 2012 23:00:00 UTC +00:00
Sat, 01 Sep 2012 00:00:00 UTC +00:00
Sun, 30 Sep 2012 23:00:00 UTC +00:00

在这里,它们被转换为 Pacific :

In Pacific

Sun, 01 Apr 2012 16:00:00 PDT -07:00
Tue, 01 May 2012 16:00:00 PDT -07:00
Fri, 01 Jun 2012 16:00:00 PDT -07:00
Sun, 01 Jul 2012 16:00:00 PDT -07:00
Wed, 01 Aug 2012 16:00:00 PDT -07:00
Fri, 31 Aug 2012 17:00:00 PDT -07:00
Sun, 30 Sep 2012 16:00:00 PDT -07:00

我还注意到我放在这里的代码对我的服务器不准确。服务器将 Time.zone 设置为最后一个作业,而不是帐户的 timezone。这意味着(或者至少我认为这意味着)时区是浮动和动态的。但这也让我感到困扰,因为加利福尼亚的夏令时直到 11 月才转换,而不是 9 月。

4

3 回答 3

0

发生这种情况的原因是,当您添加两个 DateTime 时,DateTime 对象将添加天数并破坏时区。

当您将两个 Time 对象添加在一起时,它们将按小时添加,并包括任何时区差异。

之所以会出现小时差异,是因为两个 DateTime 加在一起超出了时区更改。然后将时间以相同的数字保存到 UTC 中的数据库中,尽管事实上当它们稍后在各自的时区中解析时,它们将偏移一小时。

于 2012-08-14T12:02:23.823 回答
0

时间计算总是有问题的。1.month 可能是 30 天、31 天、28 天或介于两者之间的任何时间。这取决于添加的月份、添加的内容等等。因此,不幸的是,在进行日期算术时,这样的错误很常见,而且很烦人。

要更正此代码,我将始终确保它选择您所在月份的月初,如下所示:

new_date = (now + 1.months).beginning_of_month

那将永远是每月的 1 日。

于 2012-08-02T16:13:12.630 回答
0

你试过 .next_month 吗?http://api.rubyonrails.org/classes/Time.html#method-i-months_since

于 2012-08-02T16:30:24.707 回答