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

      

+3


source to share


4 answers


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

+5


source


This is because time is passing. Your first DateTime.now you check against is a couple of milliseconds before your second DateTime.now, in parentheses.



+2


source


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

      

+2


source


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

      

+1


source







All Articles