Lua countdown timer for months and years - lua

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

math operations with hours,minutes and seconds

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.

This code causes Corona to become unresponsive

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.

lua number format not working

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.

Countdown how to add milliseconds

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)

How to customize my timer display to show only minutes and seconds?

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

Resources