Clock app not updating correctly

Got my clock app working and seconds hand is updating as should but cant get minute hand and hour hand to update on time. First used timetable:

local timeTable = os.date("*t")

minuteHand.rotation = 6 * timeTable.min
secondHand.rotation = 6 * timeTable.sec
hourHand.rotation = 30 * timeTable.hour + 0.5 * timeTable.min

That did not make anything rotate so then added code for rotation:

timer.performWithDelay( 1000, function() secondHand.rotation = secondHand.rotation + 6; end, 0 )
timer.performWithDelay( 60000, function() minuteHand.rotation = minuteHand.rotation + 6; end, 0 )

timer.performWithDelay(3600000, function() hourHand.rotation = hourHand.rotation + 30; end, 0 )

How to get minute and hour hands to rotate in correct time?

Personally, I would count the seconds since midnight and have a single 1 second timer that worked out the relative hands rotation in that.

Given the amount of seconds you can divide by 60 for minutes and then again by 60 for hours.  Use those to calculate a rotation vector for each hand.

If you want the hands to sweep in real time then use an enterframe() listener and update at 30 fps.

How can i update my code to use real time? Basically what it does now is counting seconds from time app is open.

local time = os.time() local date = os.date("\*t", time) print("hour: " .. date.hour) print("minute: " .. date.min) print("second: " .. date.sec)

You will then simply need to map each value to 360 degrees of rotation which is real simple

Already done that just cant get it to update in real time.

Did you look up on my recommendation of enterFrame() ?

Googled enter frame and this is what i found for event time:

local function printTimeSinceStart( event )

    print ( tostring(event.time/1000) … " seconds since app started." )

end

Runtime:addEventListener( “enterFrame”, printTimeSinceStart )

So i guess need to change that not to be since start but from midnight?

Tip: You can’t rely on performWithDelay to be perfect.

It is close to perfect internally, but can’t do its work till the next qualified frame so may lag by a few milliseconds each time it executes your worker code.

It would be much better to make a clock with an enterFrame listener that re-grabs the current time and then rotates the hands accordingly.

So delete performWithDelay code? Can you explain to me how to use enterFrame to grab current time and rotate hands?

I suggest you start here - https://coronalabs.com/learn/

Here is a clock in less than 50 lines of code using SSK2 (which is now free).

https://www.youtube.com/watch?v=4dYM5gdoZMw&feature=youtu.be

Code for this example (w/o SSK 2): https://github.com/roaminggamer/RG_FreeStuff/raw/master/AskEd/2017/06/clock.zip

SSK2 Docs: https://roaminggamer.github.io/RGDocs/pages/SSK2/

SSK2 GitHub: https://github.com/roaminggamer/SSK2

You can easily convert this to raw Corona, by:

  1. Reading the code carefully and using standard corona calls for the rectangles.

  2. Use your own 2d math code or someone else’s.

  3. Use standard Runtime:* calls instead of listen:* shorthand equivalent.

However I suggest at least using my (SSK2) 2d math library.

io.output():setvbuf("no") display.setStatusBar(display.HiddenStatusBar) -- ============================================================= require "ssk2.loadSSK" \_G.ssk.init() -- Localizations local newRect = ssk.display.newRect local newCircle = ssk.display.newCircle local angle2Vector = ssk.math2d.angle2Vector local scaleVec = ssk.math2d.scale local mFloor = math.floor -- ============================================================= -- Example Begins - Uses SSK2 library! -- ============================================================= local clockGroup = display.newGroup() clockGroup.x = centerX clockGroup.y = centerY -- Draw Dial Marks local degPerTick = 360/12 for i = 1, 12 do local vec = angle2Vector( (i-1) \* degPerTick, true ) vec = scaleVec( vec, 270 ) newRect( clockGroup, vec.x, vec.y, { w = 8, h = 24, rotation = (i-1) \* degPerTick} ) end local back = newRect( nil, centerX, centerY, { w = fullw, h = fullh, fill = \_B\_, alpha = 0.15 } ) local hourHand = newRect( clockGroup, 0, 0, { w = 32, h = 180, anchorY = 1, fill = \_W\_ } ) local minHand = newRect( clockGroup, 0, 0, { w = 16, h = 220, anchorY = 1, fill = \_LIGHTGREY\_ } ) local secHand = newRect( clockGroup, 0, 0, { w = 6, h = 240, anchorY = 1, fill = \_GREY\_ } ) local dialCenter = newCircle( clockGroup, 0, 0, { radius = 40, stroke = \_DARKERGREY\_, strokeWidth = 6 } ) function back.enterFrame( self ) local tt = os.date("\*t") hourHand.rotation = tt.hour \* 360/12 minHand.rotation = tt.min \* 360/60 secHand.rotation = mFloor( tt.sec \* 360/60 ) end; listen( "enterFrame", back ) local timeTable = os.date("\*t") table.dump(timeTable)

Many thanks to all, helped me alot. Apologize for so many questions still new to learning lua.

Personally, I would count the seconds since midnight and have a single 1 second timer that worked out the relative hands rotation in that.

Given the amount of seconds you can divide by 60 for minutes and then again by 60 for hours.  Use those to calculate a rotation vector for each hand.

If you want the hands to sweep in real time then use an enterframe() listener and update at 30 fps.

How can i update my code to use real time? Basically what it does now is counting seconds from time app is open.

local time = os.time() local date = os.date("\*t", time) print("hour: " .. date.hour) print("minute: " .. date.min) print("second: " .. date.sec)

You will then simply need to map each value to 360 degrees of rotation which is real simple

Already done that just cant get it to update in real time.

Did you look up on my recommendation of enterFrame() ?

Googled enter frame and this is what i found for event time:

local function printTimeSinceStart( event )

    print ( tostring(event.time/1000) … " seconds since app started." )

end

Runtime:addEventListener( “enterFrame”, printTimeSinceStart )

So i guess need to change that not to be since start but from midnight?

Tip: You can’t rely on performWithDelay to be perfect.

It is close to perfect internally, but can’t do its work till the next qualified frame so may lag by a few milliseconds each time it executes your worker code.

It would be much better to make a clock with an enterFrame listener that re-grabs the current time and then rotates the hands accordingly.

So delete performWithDelay code? Can you explain to me how to use enterFrame to grab current time and rotate hands?