Search code examples
timeluarainmeter

How can I add minutes and seconds to a datetime in lua?


I have a lua function to attempt to convert the time duration of the currently playing song e.g. hh:mm:ss to seconds.

function toSeconds (inputstr)
    local mytable = string.gmatch(inputstr, "([^"..":".."]+)");

    local conversion = { 60, 60, 24}
    local seconds = 0;
    --iterate backwards
    local count = 0;

    for i=1, v in mytable do
        count = i+1
    end

    for i=1, v in mytable do
        mytable[count-i]
        seconds = seconds + v*conversion[i]
    end
    return seconds
end

in order to add it to os.time to get the estimated end time of a song.

but the hours may be missing, or the minutes may be missing on a short track.

When running against https://www.lua.org/cgi-bin/demo All I get is input:10: 'do' expected near 'in'

for the test script

function toSeconds (inputstr)
    local mytable = string.gmatch(inputstr, "([^"..":".."]+)");

    local conversion = { 60, 60, 24}
    local seconds = 0;
    --iterate backwards
    local count = 0;

    for i=1, v in mytable do
        count = i+1
    end

    for i=1, v in mytable do
        mytable[count-i]
        seconds = seconds + v*conversion[i]
    end
    return seconds
end

print(toSeconds("1:1:1")

Solution

  • You're mixing up the two possible ways of writing a for loop:

    a)

    for i=1,10 do
       print(i, "This loop is for counting up (or down) a number")
    end
    

    b)

    for key, value in ipairs({"hello", "world"}) do
       print(key, value, "This loop is for using an iterator function")
    end
    

    The first one, as you can see, simply counts up a number, i in this case. The second one is very generic and can be used to iterate over almost anything (for example using io.lines), but is most often used with pairs and ipairs to iterate over tables.

    You also don't write for ... in tab, where tab is a table; you have to use ipairs for that, which then returns an iterator for the table (which is a function)


    You're also using string.gmatch incorrectly; it doesn't return a table, but an iterator function over the matches of the pattern in the string, so you can use it like this:

    local matches = {}
    for word in some_string:gmatch("[^ ]") do
       table.insert(matches, word)
    end
    

    which gives you an actual table containing the matches, but if you're only going to iterate over that table, you might as well use the gmatch loop directly.


    for i=1, v in mytable do
       count = i+1
    end
    

    I think you're just trying to count the elements in the table here? You can easily get the length of a table with the # operator, so #mytable


    If you have a string like hh:mm:ss, but the hours and the minutes can be missing, the easiest thing might be to just fill them with 0. A somewhat hacky but short way to achieve this is to just append "00:00:" to your string, and look for the last 3 numbers in it:

    local hours, minutes, seconds = ("00:00:"..inputstr):match("(%d%d):(%d%d):(%d%d)$")
    

    If nothing is missing, you'll end up with something like 00:00:hh:mm:ss, which you only take the last 3 values of to end up with the correct time.