For t_sec, you first of all don’t have to take %60 twice. Taking a number modulo an integer is an involution - that is, x%60 = (x%60)%60. Furthermore, if you have 14400 + 1 seconds, then (14400 + 1)%60 evaluates to 1, as 14400 is divisible by 60. This is what it evaluates to in Lua, as well. Why you get 59 cannot be explained by the code you provided - perhaps something is wrong with your timer incrementing the time by one second.
For t_min, you would not expect to get an integer, as 14401 is not divisible by 60. Furthermore, you can never get 60 when taking someting modulo 60. Indeed, (14401 / 60)%60 evaluates to 0.0166… in Lua.
For t_hour, you would not expect to get an integer again, as 14401 is not divisible by 3600, but it is pretty damn close to 4. Indeed, 14401 / 60 / 60 evaluates to 4.000277… in Lua.
I cannot tell what is wrong with your code from the snippet you provided, but I am fairly certain it is something to do with the timer.
‘floor()’ should be ‘math.floor()’ in your example, and ‘format()’ should be ‘string.format()’, of course, but otherwise that is of course entirely equivalent to the method provided by OP.
It might, however, be possibly ever so slightly slower due to carrying out more operations. I am not certain of the complexity of the Euclidean algorithm for floating points, and the difference would be miniscule anyway
t = {
sec = 0,
min = 0,
day = 1,
isdst = false,
wday = 5,
yday = 1,
year = 1970,
month = 1,
hour = 4
}
The date part will be wrong as it’s calculating 14400 seconds since 1.1.1970 - 00:00:00 but the hours minutes and seconds should be ok. If you need the days also remember to subtract 1.
You seem to be rounding these upwards, somehow. Round them all down, and you get 3h59m59s, as you would expect.
Actually, I’m not.
My final solution was to subtract one from each value, like this:
if self.timer > 0 then
self.timer = math.max(self.timer - dt, 0) -- make sure it doesn't go below 0
local t_sec = self.timer % 60 - 1 -- because of lua, you have to -1 !!!
local t_min = (self.timer / 60) % 60 - 1 -- because of lua, you have to -1 !!!
local t_hour = self.timer / 60 / 60 - 1 -- because of lua, you have to -1 !!!
local time_string =""
if ( t_hour > 0 ) then
time_string = string.format( "%2dh %2dm %2ds", t_hour, t_min, t_sec );
else
time_string = string.format( "%2dm %2ds", t_min, t_sec );
end
print(time_string);
-- do something with time string ...
else
-- gameover!!!
end
I believe this happens because Lua treats “0” as “1” when dealing with numeric indexes of arrays.
You are getting different results from a barebones test of the modulo calculations in Lua, so Lua is innocent in this. Lua does not change the values of standard modulo calculations in any way, and modulo calculations have nothing to do with the indices of arrays. Try opening up a barebones project in Lua and doing
14399%60
(14399/60)%60
(14399/60)/60
And you will always get 59, 59.9833… and 3.999722…, respectively, and not 60, 60.9833…, and 4.99972… as happens in your code. The error definitely lies in the code for your timer.
What could be happening is that your timer is based on arrays starting their counts at 0 rather than 1, which then causes some errors. That does not mean that Lua treats 0 as 1 - it means that you are treating 1 as 0. This is a common mistake to make. It is impossible to tell without the code provided, however.
Feel free to post the code for the timer. Fixing it with a bandaid solution like subtracting 1 from the result is not a very stable solution, so I’d love to help fix it.
No, I am running your code example and get the same result as others above (in Lua 5.3, in Defold Lua and also in Python). The bug must be elsewhere, in code that you have not posted.