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.