简体   繁体   中英

Lua - calculating if a time is between two time stamps

Given the following examples:

--Test current     start     end     between
--1    10:00       09:00     12:00   true
--2    01:00       07:34     09:54   false
--3    17:00       16:00     03:00   true
--4    10:00       10:00     15:00   true
--5    10:30       10:00     10:30   true

In Lua, how is it best to create a function that I can call:

BetweenTimes ("10:00", "09:00","12:00")

and in this case (Test 1) return true. The issue I have is will Test case 3.

I can assume that the first time is always before the second time.

I think this might be it:

local function parse_time(str)
   local hour, min = str:match("(%d+):(%d+)")
   return os.time{hour = hour, min = min, day = 1, month = 1, year = 1970}
end

local function BetweenTimes(between, start, stop)
   between = parse_time(between)
   start   = parse_time(start)
   stop    = parse_time(stop)

   if stop < start then
      return (start <= between) or (between <= stop)
   else
      return (start <= between) and (between <= stop)
   end
end

print(BetweenTimes("10:00", "09:00", "12:00")) -- true
print(BetweenTimes("15:00", "09:00", "12:00")) -- false
print(BetweenTimes("15:00", "09:00", "01:00")) -- true
print(BetweenTimes("10:00", "10:00", "11:00")) -- true
print(BetweenTimes("11:00", "10:00", "11:00")) -- true
print(BetweenTimes("19:00", "17:00", "03:30")) -- true
print(BetweenTimes("03:00", "04:00", "05:30")) -- false
print(BetweenTimes("03:00", "02:00", "05:30")) -- true
print(BetweenTimes("01:00", "09:00", "02:30")) -- true

or even just the following should work to remove os.time() :

local function BetweenTimes(between, start, stop)
   local start   = string.gsub(start,":", "")
   local between = string.gsub(between,":", "") 
   local stop    = string.gsub(stop,":", "") 

   if stop < start then
      return (start <= between) or (between <= stop)
   else
      return (start <= between) and (between <= stop)
   end
end

Your approach sounds overly complicated. Just parse the hours and minutes out of the string and convert it to a UNIX timestamp. These are regular integers and you can easily compare them using < and > .

local function parse_time(str)
   local hour, min = str:match("(%d+):(%d+)")
   return os.time{hour = hour, min = min, day = 1, month = 1, year = 1970}
end

local function BetweenTimes(between, start, stop)
   between = parse_time(between)
   start   = parse_time(start)
   stop    = parse_time(stop)
   if stop < start then
      stop = stop + 24*60*60 -- add 24 h
   end
   return (start <= between) and (between <= stop)
end

print(BetweenTimes("10:00", "09:00", "12:00")) -- true
print(BetweenTimes("15:00", "09:00", "12:00")) -- false
print(BetweenTimes("15:00", "09:00", "01:00")) -- true

Why are you even using the date when you only have hours and minutes? Unless you expect to handle any other time units in future, a simple multiplication will suffice.

local function parse_time(str)
   local hour, min = str:match("(%d+):(%d+)")
   return min * 60 + hour
end

I won't copy BetweenTimes from Henri Menke's answer - it is exactly the same with the only change inside wrapping handling because my parse_time returns minutes, not seconds:

stop = stop + 24*60

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM