When dealing with Time objects in Ruby, I hit a boundary problem. If you do it normally, you won’t have that much of a problem using the Range object, but I stumbled over something unusual.
Ruby: 2.6.2 Rails: 5.1.2
The problem I was addicted to in the first place
Time.now.end_of_day => 2020-05-15 23:59:59 +0900
I want to take the next value of this.
- Because end_of_day is easy to understand, I only use it, and I do not want the beginning and end of a certain day. The next value of the Time object until you get tired of it
This was the first thing I came up with.
Time.now.end_of_day + 1 => 2020-05-16 00:00:00 +0900
But this is wrong
(Time.now.end_of_day + 1).iso8601(3) => "2020-05-16T00:00:00.999+09:00"
You can’t use
+ 1 because it adds 1 second until you get tired of it, and does not move to the next value.
When I was fishing the Time class, I found a method that looked very similar https://docs.ruby-lang.org/ja/latest/method/Time/i/succ.html
Time.now.end_of_day.succ (pry):109: warning: Time#succ is obsolete; use time + 1 => 2020-05-16 00:00:00 +0900
However, it seems that he is doing the same thing as
+ 1 because he is angry when he uses it because it is outdated. No good.
After all I did not know the good way, so I pushed it
As for the problem of the example, I have seen only the decimal 9 digits
(Time.now.end_of_day + 1).iso8601(10) => "2020-05-16T00:00:00.9999999990+09:00"
In other words, add 1 nanosecond
(Time.now.end_of_day + 1/1000000000.0).iso8601(9) => "2020-05-16T00:00:00.000000000+09:00"
Time.now.iso8601(10) => "2020-05-15T19:56:55.4979370000+09:00" Time.new(2020, 5, 16, 16, 59, 59.3).iso8601(9) => "2020-05-16T16:59:59.299999999+09:00" Time.parse("2020-05-16T16:59:59.3+09:00").iso8601(9) => "2020-05-16T16:59:59.300000000+09:00" Time.parse("2020-05-16T16:59:59.35555555555555555555+09:00").iso8601(20) => "2020-05-16T16:59:59.35555555555555555555+09:00"
It was no good
- The number of fractional seconds in the Time object can be infinite
- Therefore, there is no concept of the next value
- However, it depends on how to generate the Time object, so if you pull it from the DB, you cannot force it if you consider the number of significant digits.
- In the first place, it should be compared without using the Range object in the first place