首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Rails时代的奇怪之处:“从现在起x天”

问Rails时代的奇怪之处:“从现在起x天”
EN

Stack Overflow用户
提问于 2010-10-29 10:30:03
回答 3查看 27.2K关注 0票数 17

当用户注册到我的一个网站进行免费试用时,我将他们的帐户过期设置为"14.days.from_now“。然后在主页上显示他们还有多少天,我得到了:

代码语言:javascript
复制
(user.trial_expires - Time.now)/86400 

(因为一天有86400秒( 60 * 60 * 24) )

有趣的是,这个结果超过了14,所以会被围捕到15。如果在控制台进行更仔细的调查,这种情况在未来只会持续两天(如果你知道我的意思)。例如

代码语言:javascript
复制
>> Time.now
=> Fri Oct 29 11:09:26 0100 2010
>> future_1_day = 1.day.from_now
=> Sat, 30 Oct 2010 11:09:27 BST 01:00
#ten past eleven tomorrow

>> (future_1_day - Time.now)/86400
=> 0.999782301526931
#less than 1, what you'd expect right?

>> future_2_day = 2.day.from_now
=> Sun, 31 Oct 2010 11:09:52 GMT 00:00
>> (future_2_day - Time.now)/86400
=> 2.04162248861183
#greater than 2 - why?

我想这可能与时区有关-我注意到从1天开始的时间是在BST,2天后的时间是在格林尼治时间。所以,我尝试使用本地时间,并得到了同样的结果!

代码语言:javascript
复制
>> future_2_day = 2.day.from_now.localtime
=> Sun Oct 31 11:11:24 0000 2010
>> (future_2_day - Time.now)/86400
=> 2.04160829127315
>> (future_2_day - Time.now.localtime)/86400
=> 2.04058651585648

然后我想知道差别有多大,结果却是一个小时的路程。所以它看起来像是一些时区的怪异,或者至少是一些我不明白的时区。目前,我的时区是英国夏令时间( BST ),目前它比UTC晚了一个小时(直到这个星期天,它恢复到了和UTC一样的水平)。

当我将两天的时间添加到Time.now中时,似乎引入了额外的时间:看看这个。我从Time.now开始,加上两天,减去Time.now,然后从结果中减去两天的秒,然后剩下一个小时。

我突然想到,这是因为时钟在星期天早上11点20分倒转,从现在起,这将是两天零1小时。我正要删除所有这篇文章,但后来我注意到:我想‘啊,我可以用(24*daynum).hours而不是daynum.days来修复这个问题,但是我仍然得到了相同的结果:即使我使用秒!

代码语言:javascript
复制
>> (Time.now + (2*24).hours - Time.now) - 86400*2
=> 3599.99969500001
>> (Time.now + (2*24*3600).seconds - Time.now) - 86400*2
=> 3599.999855

所以现在我又糊涂了。现在加上两天的秒,减去现在的两天,减去两秒,怎么能等于一小时的秒呢?额外的时间从哪里溜进来?

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2010-10-29 10:53:24

正如燕麦食品所评论的,这是由于夏令时间在本周末结束。

当添加持续时间时,ActiveSupport中有一些代码来补偿启动时间在DST中,而产生的时间不是(反之亦然)。

代码语言:javascript
复制
def since(seconds)
  f = seconds.since(self)
  if ActiveSupport::Duration === seconds
    f
  else
    initial_dst = self.dst? ? 1 : 0
    final_dst   = f.dst? ? 1 : 0
    (seconds.abs >= 86400 && initial_dst != final_dst) ? f + (initial_dst - final_dst).hours : f
  end
rescue
  self.to_datetime.since(seconds)
end

如果你有11:09:27,加上一些日子,即使DST改变了,你也会得到11:09:27。当你在几秒钟内进行计算时,这会导致额外的一个小时。

有几个想法:

  • 使用distance_of_time_in_words助手方法可以指示用户在试用中还有多长时间。
  • 将过期时间计算为Time.now + (14 * 86400),而不是使用14.days.from_now --但一些用户可能会声称,他们已经失去了一个小时的试用时间。
  • 将试验设定为23:59:59在期满日结束,而不考虑实际注册时间。
票数 19
EN

Stack Overflow用户

发布于 2010-10-29 12:36:43

您可以使用日期类计算从今天到到期日期之间的天数。

代码语言:javascript
复制
expire_date = Date.new(user.trial_expires.year, user.trial_expires.month, user.trial_expires.day)
days_until_expiration = (expire_date - Date.today).to_i
票数 8
EN

Stack Overflow用户

发布于 2014-08-18 18:35:20

使用since,示例: 14.days.since.to_date

票数 5
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/4050991

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档