NathanB
NathanB

Reputation: 105

Find out if current time is between two times

I have two time columns stored in a Postgresql database: open_time and close_time. I'm trying to find out if the current time, ignoring the date, is between the two times, ignoring the dates.

This code compares the dates as well as the time:

current_time = Time.now
if current_time.between?(store.open_time, store.close_time)
  puts "IN BETWEEN"      
end

It doesn't work, for example, when current_time # => 2018-06-06 23:59:49 -0600 and open_time # => 2000-01-01 22:59:00 UTC.

How do I get it to not include the dates, and just compare the times?

Upvotes: 0

Views: 567

Answers (4)

Martin
Martin

Reputation: 2414

You could CAST() your datetime to time by using,

cast(tbl_store.open_time as time) as SomeVariable

cast(tbl_store.close_time as time) as SomeOtherVariable

That would give you the time only instead of the full datetime value that you had to begin with, which is what you wanted.

You can then use the same logic with your curtime() between to the get value that you were looking for.

Example:

SELECT
  CAST(tbl_store.open_time as TIME) as open_time,
  CAST(tbl_store.close_time as TIME) as close_time,
  CURTIME() BETWEEN (cast(tbl_store.open_time as TIME)) AND (cast(tbl_store.close_time as TIME)) as time_between
FROM
  tbl_store

Working SQL Fiddle

You can change the schema build in the fiddle to test the datetime values you desire.

Note that if you ever have a logic that will include midnight time, you will have to make a CASE WHEN logic against that, else it will fail and return 0, whereas it should return 1.

Upvotes: 2

Cary Swoveland
Cary Swoveland

Reputation: 110665

require 'time'

TIME_FMT = "%H%M%S"

def store_open_now?(open_time, close_time)
  nt = Time.now.strftime(TIME_FMT)
  ot = open_time.strftime(TIME_FMT)
  ct = close_time.strftime(TIME_FMT)
  ot <= ct ? (nt >= ot && nt <= ct) : (nt >= ot || nt <= ct)
end

As I write, the time is now about 32 minutes past midnight.

Time.now.strftime(TIME_FMT)
  #=> "003252"

Suppose

open_time  = DateTime.parse("09:00")
  #=> #<DateTime: 2018-06-07T09:00:00+00:00 ((2458277j,32400s,0n),
  #               +0s,2299161j)>
close_time = DateTime.parse("17:00")
  #=> #<DateTime: 2018-06-07T17:00:00+00:00 ((2458277j,61200s,0n),
  #               +0s,2299161j)>

Then

open_time.strftime(TIME_FMT)
  #=> "090000"
close_time.strftime(TIME_FMT)
  #=> "170000"
store_open_now?(open_time, close_time)
  #=> false

Now suppose the open time is the same, but the close time is later.

close_time = DateTime.parse("01:00")
  #=> #<DateTime: 2018-06-07T01:00:00+00:00 ((2458277j,3600s,0n),
  #               +0s,2299161j)>

Then

close_time.strftime(TIME_FMT)
  #=> "010000"
store_open_now?(open_time, close_time)
  #=> true

Upvotes: 7

lunohodov
lunohodov

Reputation: 5399

You can take advantage of ranges and how numeric strings are compared

r = Range.new('09:00', '18:00')

r.include?('08:59') # => false
r.include?('09:01') # => true
r.include?('18:01') # => false

Then we could use

open_hours_range = Range.new(open_time.strftime('%R'), close_time.strftime('%R'))
shop_open? = open_hours_range.include?(Time.now.strftime('%R'))

Upvotes: 0

sawa
sawa

Reputation: 168081

Perhaps you want something like this:

current_time = Time.now
open_time = store.open_time
close_time = store.close_time
current_time -= current_time.beginning_of_day
open_time -= open_time.beginning_of_day
close_time -= close_time.beginning_of_day
if current_time.between?(open_time, close_time)
  puts "IN BETWEEN"      
end

or

current_time = Time.now
open_time = store.open_time
close_time = store.close_time
current_time = [current_time.hour, current_time.min, current_time.sec]
open_time = [open_time.hour, open_time.min, open_time.sec]
close_time = [close_time.hour, close_time.min, close_time.sec]
if open_time <=> current_time == -1 and current_time <=> close_time == -1
  puts "IN BETWEEN"      
end

Upvotes: 4

Related Questions