Below is an example of a countdown timer for Corona SDK written in LUA.
How would I add days, months and years to this?
local function updateTime()
-- decrement the number of seconds
secondsLeft = secondsLeft - 1
-- time is tracked in seconds. We need to convert it to minutes and seconds
local minutes = math.floor( secondsLeft / 60 )
local seconds = secondsLeft % 60
-- make it a string using string format.
local timeDisplay = string.format( "%02d:%02d", minutes, seconds )
clockText.text = timeDisplay
end
Days (and hours) would be trivial, but what about months and years? Since you have no timestamp telling us of how many seconds left to what, it's hard knowing exactly how many months, depending on the length of the months (28, 29, 30 or 31 days). The same with years if we consider leap years as well. In any case, here's something that might be sufficient:
local SECONDS_IN_HOUR = 60 * 60
local SECONDS_IN_DAY = 24 * SECONDS_IN_HOUR
local SECONDS_IN_MONTH = 30 * SECONDS_IN_DAY -- assuming an average of 30 days per month
local SECONDS_IN_YEAR = 365 * SECONDS_IN_DAY
local years = math.floor((secondsLeft / SECONDS_IN_YEAR) % 365)
local months = math.floor((secondsLeft / SECONDS_IN_MONTH) % 12)
local days = math.floor((secondsLeft / SECONDS_IN_DAY) % 30)
local hours = math.floor((secondsLeft / SECONDS_IN_HOUR) % 24)
local minutes = math.floor((secondsLeft / 60) % 60)
local seconds = secondsLeft % 60
Related
I work with decimal times in Lua and make arithmetical operations on them.
For example 124500+5=124505 (12:45:05)
What formula can avoid 60 digits problem?
124459+5=124504 (not 124464)
How can I resolve it?
You are mixing formation with calculation. The best way is to transform your time "string" in a real number:
12:45:05 -> 12 * 60 * 60 + 45 * 60 + 05 = 45905
The function could look like this:
function time_to_number(t)
return (math.floor(t / 10000) * 60 * 60) + ((math.floor(t / 100) % 100) * 60) + (t % 100)
-- you can also use % 10000 if the hours are limited to two digits
end
Now you can calculate on the seconds.
To format the value back you can use this function
function time_split(t)
local hour = math.floor(t / 3600)
local min = math.floor((t % 3600) / 60)
local sec = (t % 3600) % 60
return hour, min, sec
end
I have used many brackets for readability, which are not all required.
When I run this code in Corona on Windows 7 it instantly crashes. It works fine in ZeroBrane. Any ideas why?
--Stopwatch--
local startTime
function start()
startTime = os.time()
--Start the stop watch--
end
function secondsEllapsed()
--Return the number of seconds since the stop watch was started--
return os.time() - startTime
end
start()
while true do
-- Get the time ellapsed and convert it to hours, minutes and seconds
ellapsed = secondsEllapsed()
hours = math.floor(ellapsed / 3600)
minutes = math.floor((ellapsed - (hours * 3600)) / 60)
seconds = math.floor((ellapsed - (hours * 3600) - (minutes * 60)))
-- Print the time ellapsed to the command line
print(hours .. 'h', minutes .. 'm', seconds .. 's')
end
It crashes probably because you run infinity loop.
I have the following function:
function timestamp(duration)
local hours = duration / 3600
local minutes = duration % 3600 / 60
local seconds = duration % 60
return string.format("%02d:%02d:%02.03f", hours, minutes, seconds)
end
when the duration is 4.404 sec it returns 00:00:4.404
what is am looking for is 00:00:04.404
It should be:
string.format("%02d:%02d:%06.3f", hours, minutes, seconds)
Field width contains all characters of the number, including point and fraction.
The below countdown clock works from seconds, minutes, days, months, year, how would I add milliseconds to this?
local secondsLeft = 3.154e + 7
-- one year
local clockText = display.newText("00.00:00:00:00", display.contentCenterX, 80, "font1.ttf", 60)
sceneGroup:insert(bg)
sceneGroup:insert(title)
sceneGroup:insert(summary)
sceneGroup:insert(clockText)
sceneGroup:insert(clockText)
local SECONDS_IN_HOUR = 60 * 60
local SECONDS_IN_DAY = 24 * SECONDS_IN_HOUR
local SECONDS_IN_MONTH = 30 * SECONDS_IN_DAY
-- assuming an average of 30 days per month
local SECONDS_IN_YEAR = 365 * SECONDS_IN_DAY
local function updateTime()
-- decrement the number of seconds
secondsLeft = secondsLeft - 1
-- time is tracked in seconds. We need to convert it to minutes and seconds
local years = math.floor((secondsLeft / SECONDS_IN_YEAR) % 365)
local months = math.floor((secondsLeft / SECONDS_IN_MONTH) % 12)
local days = math.floor((secondsLeft / SECONDS_IN_DAY) % 30)
local hours = math.floor((secondsLeft / SECONDS_IN_HOUR) % 24)
local minutes = math.floor((secondsLeft / 60) % 60)
local seconds = secondsLeft % 60
-- make it a string using string format.
local timeDisplay = string.format("%02d·%02d·%02d·%02d·%02d·%02d", years, months, days, hours, minutes, seconds)
clockText.text = timeDisplay
end
local countDownTimer = timer.performWithDelay(100, updateTime, secondsLeft)
Here's an example, maybe useful for you:
local sceneGroup = display.newGroup()
local totalSecond = 5 * 1000 -- 5 sceonds
local clockText = display.newText("", display.contentCenterX, 80, native.systemFontBold, 30)
--sceneGroup:insert(bg)
--sceneGroup:insert(title)
--sceneGroup:insert(summary)
sceneGroup:insert(clockText)
sceneGroup:insert(clockText)
local SECONDS_IN_HOUR = 60 * 60
local SECONDS_IN_DAY = 24 * SECONDS_IN_HOUR
local SECONDS_IN_MONTH = 30 * SECONDS_IN_DAY -- assuming an average of 30 days per month
local SECONDS_IN_YEAR = 365 * SECONDS_IN_DAY
function updateTime(msLeft)
-- decrement the number of seconds
if totalSecond >= msLeft then
local secondsLeft = totalSecond - msLeft
-- time is tracked in seconds. We need to convert it to minutes and seconds
local years = math.floor((secondsLeft / 1000 / SECONDS_IN_YEAR) % 365)
local months = math.floor((secondsLeft / 1000 / SECONDS_IN_MONTH) % 12)
local days = math.floor((secondsLeft / 1000 / SECONDS_IN_DAY) % 30)
local hours = math.floor((secondsLeft / 1000 / SECONDS_IN_HOUR) % 24)
local minutes = math.floor((secondsLeft / 1000 / 60) % 60)
local seconds = math.floor(secondsLeft / 1000 % 60)
local msceonds = secondsLeft % 1000
-- make it a string using string format.
local timeDisplay = string.format("%02dY·%02dM·%02dD·%02dH·%02dM·%02dS·%03dMS", years, months, days, hours, minutes, seconds, msceonds)
clockText.text = timeDisplay
else
clockText.text = "Time's up!"
Runtime:removeEventListener("enterFrame", enterFrameListener)
end
end
function enterFrameListener(e)
updateTime(e.time)
end
Runtime:addEventListener("enterFrame", enterFrameListener)
My Timer is displaying Minutes and Hours, but once it gets to 60 minutes it restarts from 0 Minute.
Should I get rid of the modulo ( % 60 ) for minutes.
I would like my timer to display for ex: 80:45 ( basically not stopping at 60 min once it reaches 1 hour)
var min = 0
var sec = 0
func stringFromTimeInterval(interval: NSTimeInterval) -> String {
let interval = Int(interval)
let seconds = interval % 60
let minutes = (interval / 60) % 60
//let hours = (interval / 3600)// I don't need the hours
return String(format: "%02d:%02d",minutes, seconds)
}
% 60 means that it will spit out a minutes value that is the remainder when divided by 60(minutes). This is most probably because for time in the form hh:mm, you want it to go from 5:59 to 6:00, not 5:60. So changing the following line will give you what you seek.
let minutes = (interval / 60) % 60 -> let minutes = interval / 60