Home > database >  How do i format time into seconds in lua?
How do i format time into seconds in lua?

Time:06-19

So basically I'm confused on how I'd make it so that I can convert DD:HH:MM:SS to only seconds while taking into account the amount of numbers there are. (Sorry if I make 0 sense, you should definitely know what I mean by the example below.)

print("05:00":FormatToSeconds()) -- 5 minutes and 0 seconds
-- 300

print("10:30:15":FormatToSeconds()) -- 10 hours, 30 minutes and 15 seconds
-- 37815

print("1:00:00:00":FormatToSeconds()) -- 1 day
-- 86400

print("10:00:00:30":FormatToSeconds()) -- 10 days, 30 seconds
-- 864030

So on and so forth. I think that maybe using gmatch would work but still idk. Help would be greatly appreciated.

Edit:

So I've tried doing it with gmatch, but I don't know if this is the most fastest way of doing this (which it probably isn't), so any help would still be appreciated.

(My code)

function ConvertTimeToSeconds(Time)
    local Thingy = {}
    local TimeInSeconds = 0
    
    for v in string.gmatch(Time, "%d ") do
        if tonumber(string.sub(v, 1, 1)) == 0 then
            table.insert(Thingy, tonumber(string.sub(v, 2, 2)))
        else
            table.insert(Thingy, tonumber(v))
        end
    end
    
    if #Thingy == 1 then
        TimeInSeconds = TimeInSeconds   Thingy[1]
    elseif #Thingy == 2 then
        TimeInSeconds = TimeInSeconds   (Thingy[1] * 60)   Thingy[2]
    elseif #Thingy == 3 then
        TimeInSeconds = TimeInSeconds   (Thingy[1] * 60 * 60)   (Thingy[2] * 60)   Thingy[3]
    elseif #Thingy == 4 then
        TimeInSeconds = TimeInSeconds   (Thingy[1] * 24 * 60 * 60)   (Thingy[2] * 60 * 60)   (Thingy[3] * 60)   Thingy[4]
    end
    
    return TimeInSeconds
end

print(ConvertTimeToSeconds("1:00:00:00"))

CodePudding user response:

Don't worry about execution speed before doing any actual measurements unless you're designing a time-critical program. In any extreme situation you'd probably want to offload risky parts to a C module.

Your approach is just fine. There are parts you can clean up: you can just return the results of calculations as TimeInSeconds doesn't actually act as accumulator in your case; tonumber handles '00' just fine and it can ensure decimal integers with an argument (since 5.3).

I'd go the other way and describe factors in a table:

local Factors = {1, 60, 60 * 60, 60 * 60 * 24}
local
function ConvertTimeToSeconds(Time)
  local Components = {}
  for v in string.gmatch(Time, "%d ") do
    table.insert(Components, 1, tonumber(v, 10))
  end
  if #Components > #Factors then
    error("unexpected time component")
  end
  local TimeInSeconds = 0
  for i, v in ipairs(Components) do
    TimeInSeconds = TimeInSeconds   v * Factors[i]
  end
  return TimeInSeconds
end

Of course, both implementations have problem with pattern being naïve as it would match e.g., '00 what 10 ever 10'. To fix that, you could go another route of using string.match with e.g., '(%d ):(%d ):(%d ):(%d )' and enforcing strict format, or matching each possible variant.

Otherwise you can go all in and use LPeg to parse the duration.

Another way would be to not use strings internally, but instead convert them into a table like {secs=10, mins=1, hours=10, days=1} and then use these tables instead - getting seconds from that representation would be straight-forward.

  • Related