当用户注册到我的一个网站进行免费试用时,我将他们的帐户过期设置为"14.days.from_now“。然后在主页上显示他们还有多少天,我得到了:
(user.trial_expires - Time.now)/86400 (因为一天有86400秒( 60 * 60 * 24) )
有趣的是,这个结果超过了14,所以会被围捕到15。如果在控制台进行更仔细的调查,这种情况在未来只会持续两天(如果你知道我的意思)。例如
>> 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天后的时间是在格林尼治时间。所以,我尝试使用本地时间,并得到了同样的结果!
>> 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来修复这个问题,但是我仍然得到了相同的结果:即使我使用秒!
>> (Time.now + (2*24).hours - Time.now) - 86400*2
=> 3599.99969500001
>> (Time.now + (2*24*3600).seconds - Time.now) - 86400*2
=> 3599.999855所以现在我又糊涂了。现在加上两天的秒,减去现在的两天,减去两秒,怎么能等于一小时的秒呢?额外的时间从哪里溜进来?
发布于 2010-10-29 10:53:24
正如燕麦食品所评论的,这是由于夏令时间在本周末结束。
当添加持续时间时,ActiveSupport中有一些代码来补偿启动时间在DST中,而产生的时间不是(反之亦然)。
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 --但一些用户可能会声称,他们已经失去了一个小时的试用时间。发布于 2010-10-29 12:36:43
您可以使用日期类计算从今天到到期日期之间的天数。
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发布于 2014-08-18 18:35:20
使用since,示例: 14.days.since.to_date
https://stackoverflow.com/questions/4050991
复制相似问题