ユーザーが私のサイトの1つに無料トライアルにサインアップすると、アカウントの有効期限を「14.days.from_now」に設定します。次に、ホームページに残りの日数を表示します。
(user.trial_expires - Time.now)/86400
(1日に86400秒、つまり60 * 60 * 24があるため)
面白いことに、これは14以上になるので、15に切り上げられます。コンソールで詳しく調べると、これは将来2日間だけ発生します(意味がわかっている場合)。例えば
>> 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日後の時刻がGMTであることに気付きました。だから、私は現地時間を使ってみましたが、同じ結果が得られました!
>> 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
それから私はその違いがどれほど大きいのか疑問に思いました、そしてそれははちょうど1時間であることがわかりました。だから、それはいくつかのタイムゾーンの奇妙さ、または少なくとも私が理解していないタイムゾーンと関係があるように見えます。現在、私のタイムゾーンはBST(英国夏時間)で、現時点ではUTCより1時間遅れています(この日曜日まではUTCと同じに戻ります)。
Time.nowに2日を追加すると、余分な時間が導入されるようです。これを確認してください。 Time.nowから始めて、それに2日を加算し、Time.nowを減算してから、結果から2日の秒を減算すると、1時間が残ります。
時計が日曜日の朝に戻るため、頭を叩く瞬間に、これが起こっていることに気づきました。つまり、日曜日の朝の11.20に、will今から2日と1時間余分になります。私はこの投稿をすべて削除しようとしていましたが、これに気づきました:ああ、daynum.daysの代わりに(24 * daynum).hoursを使用してこれを修正できると思いましたが、それでも同じ結果が得られます:私は秒を使います!
>> (Time.now + (2*24).hours - Time.now) - 86400*2
=> 3599.99969500001
>> (Time.now + (2*24*3600).seconds - Time.now) - 86400*2
=> 3599.999855
だから今、私は再び混乱しています。プラス2日相当の秒、マイナス今マイナス2日相当の秒を、1時間相当の秒にするにはどうすればよいでしょうか。余分な時間はどこに忍び込みますか?
willcodejavaforfood がコメントしているように、これは今週末に終了する夏時間によるものです。
期間を追加する場合、ActiveSupportには、開始時刻がDSTであり、結果の時刻が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
_ヘルパーメソッドを使用して、トライアルの残り時間をユーザーに示します。14.days.from_now
_を使用する代わりにTime.now + (14 * 86400)
として計算します。ただし、一部のユーザーは、1時間の試用期間を失ったと主張する場合があります。Date クラスを使用して、今日から有効期限までの日数を計算できます。
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
since
を使用します。例:14.days.since.to_date