Convert a time string into seconds using string patterns

For those familiar with string patterns, how would you effectively convert timeString (i.e. a string representing a length of time with identifiers such as ‘h’ for hours, ‘d’ for days, etc) into seconds, assuming timeString can be any assortment and length of characters without whitespaces?

local function convertTimeStringToSeconds(timeString)
	local totalSeconds = 0
	local patternValues = {
		["s"] = 1, -- seconds
		["m"] = 60, -- minutes
		["h"] = 3600, -- hours
		["d"] = 86400, -- days
		["w"] = 604800, -- weeks
		["o"] = 2628000, -- months
		["y"] = 31540000, -- years
	}
	-- Use string patterns and patternValues to determine the total time in seconds
	return totalSeconds
end
print(convertTimeStringToSeconds("10d5h1s"))

882001

1 Like

I’d group the string into value and the time unit, the first one being a value, while the 2nd group being time identifier (%d+)(%a). Using string.gmatch, it repeats this process. The first group gets all the digits until it isn’t a digit and the 2nd group to get the time identifier, then use that group string to get the hash of patternValues.

Something like

local totalSeconds = 0
for value, unit in string.gmatch("(%d+)(%a)", timeString) do
        totalSeconds += value * patternValues[unit]
end
1 Like

The method sounds solid although the code sample you provided doesn’t appear to function as intended, any thoughts why?

local function convertTimeStringToSeconds(timeString)
	local totalSeconds = 0
	local patternValues = {
		["s"] = 1, -- seconds
		["m"] = 60, -- minutes
		["h"] = 3600, -- hours
		["d"] = 86400, -- days
		["w"] = 604800, -- weeks
		["o"] = 2628000, -- months
		["y"] = 31540000, -- years
	}
	for value, unit in string.gmatch("(%d+)(%a)", timeString) do
		totalSeconds += value * patternValues[unit]
	end
	return totalSeconds
end
print(convertTimeStringToSeconds("10d5h1s"))

0

1 Like

The first argument was the string to match, the 2nd argument is the string pattern. I somehow got it the other way round :man_facepalming:
Switching the argument should work now.

string.gmatch(timeString, "(%d+)(%a)")
2 Likes