Why between? work differently for Date and DateTime in ruby?
doc says:
between? (min, max) public
Returns true if the object's current time is within the specified minimum and maximum time.
In Ruby:
>> DateTime.now.between?(DateTime.now, DateTime.now+1)
=> false
>> Date.today.between?(Date.today, Date.today+1)
=> true
Using .current
in Rails, the discrepancy becomes even clearer because you specifically expect this method to have similar behavior on DateTime
and Date
:
>> DateTime.current.between?(DateTime.current, DateTime.current+1)
=> false
>> Date.current.between?(Date.current, Date.current+1)
=> true
Is this intentional behavior? If so, why? It seems rather odd that the behavior when dealing with the edge of an min
interval is not special. Especially considering that the piece max
is special:
>> DateTime.now.between?(DateTime.now-1, DateTime.now)
=> true
>> Date.today.between?(Date.today-1, Date.today)
=> true
source to share
Lets start irb and run this code:
"#{DateTime.now.inspect} \n #{DateTime.now.inspect}"
The result will be something like this:
#<DateTime: 2017-03-22T11:42:28+03:00 ((2457835j,31348s,373353553n),+10800s,2299161j)>
#<DateTime: 2017-03-22T11:42:28+03:00 ((2457835j,31348s,373449152n),+10800s,2299161j)>
As you can see, the difference is in nanoseconds (373353553n <373449152n)
Suppose the difference is "x" and DateTime.now is "Now", then:
1) DateTime.now.between? (DateTime.now, DateTime.now + 1.seconds)
Now.between? (Now + x, Now + x + x + 1.second) => false
2) DateTime.now.between? (DateTime.now-1, DateTime.now)
Now in between? (now + x-1. second, now + x + x) => true
source to share
As others have said:
a.between?(b,c)
a
is interpreted a few milliseconds before b
and c
.
The shortest way to get the desired result:
(now=DateTime.now).between?(now, now+1)
#=> true
You can also reverse the order in which objects are initialized DateTime
:
(DateTime.now..DateTime.now+1).cover? DateTime.now
#=> true
source to share
Well it looks like its a few milliseconds problem
DateTime.now.between?(DateTime.now, DateTime.now+1)
^ executing first ^ executing after few milliseconds or nanoseconds
The meaning DateTime
with what you are comparing is deprecated than
DateTime value in
between? `
But if you store it in a variable
now = DateTime.now
now.between?(now,now+1)
#=> true
Also, as @ndn commented
DateTime.now == DateTime.now
#=> false
source to share