# is is.clock real time or CPU time? I need elapsed subsecond timing

I’d like to have an event happening every 1/4 second. os.time turns over once a second. os.clock is subsecond but is described as “CPU time”. Is it that, or is it elapsed time? If it’s CPU time, is the a way to get wall clock fractional seconds?

Thanks!

@RonJeffries Use tween delay to execute a function every .25 seconds.

``````viewer.mode=STANDARD

function setup()
start=true
count=0
end

function draw()
background(0)
if start then
start=false
count=count+1
tween.delay(.25,run)
end
end

function run()
print(count)
start=true
end
``````

@dave1707 That’s not 1/4s on the wall clock though. That’s every 1/4s since the program started, and it will also gradually drift as it runs at it has to wait for the next frame before updating.

@RonJeffries If I’ve understood you correctly, here’s some code that I have to achieve that end. It combines `os.date()`, which is wall time accurate to the second, with `ElapsedTime`, which is millisecond accurate but counts since the start of the program.

Basically, we try to get an accurate reading on `ElapsedTime` when `os.date()` clicks over from one second to the next. This then allows us to use `ElapsedTime` to calculate the current millisecond reading and thus provide an accurate timestamp.

The difficulty is that we can only examine our “clocks” each frame. This makes it complicated as we can’t tell exactly when `os.date()` clicks over from one second to the next.

I actually wrote this up for the Big Lockdown Math-Off (scroll down half way, also ignore the results of the vote!).

Here’s the code. We want to note the exact `ElapsedTime` when `os.date()` ticks over from one second to the next. All we can actually say is that it happened between one frame and the next which gives us an upper and lower limit on the millisecond reading. By continually readjusting, we can zero in on the actual reading.

Here’s some code:

``````local __l = 0
local __h = 1
local __psec
local __pet

function Now()
local t = os.date("*t")
local et = ElapsedTime
if __psec ~= nil and t.sec ~= __psec then
local a,b = __pet - math.floor(__pet), et - math.floor(__pet)
if b - a < .5 then
if __l + 1 < b then
a,b = a-1, b-1
end
__l = math.max(__l,a)
__h = math.max(__h,b)
end
end
lower = __l
higher = __h
__pet = et
__psec = t.sec
et = et - (__l + __h)/2
local time = {}
time.msec = (et - math.floor(et))*1000
time.sec = t.sec
time.min = t.min
time.hour = t.hour
time.yday = t.yday
return time
end
``````

@LoopSpace Looking at the first post, @RonJeffries didn’t say how exact he wanted it to be over a long of a period of time. That’s why I just chose tween delay. If it needs to be almost exact over a long period (according to the wall clock), I think this code will work. It uses the socket “gettime” function which I think is pretty accurate to several decimal places.

The time interval can be changed in the call to checkDuration(). This code prints the gettime every .25 seconds.

``````viewer.mode=STANDARD

function setup()
s=require("socket")
st=s:gettime()
c=0
end

function draw()
background(0)
checkDuration(.25)
end

function checkDuration(d)
local i=s:gettime()-st
if i>c then
c=c+d
xx()
end
end

function xx()
print(s:gettime())
end
``````

and i completely forgot ElapsedTime, which really ought to be mentioned in the time tab of the docs. @LoopSpace neat … far more than i needed. and res, @dave1707, maybe tween delay will be better. thanks for reminder. i think my head was empty today.

ElapsedTime isn’t that reliable if the FPS starts to drop. Here’s an example. Slide the slider and see what happens to the ElapsedTime that’s displayed.

``````viewer.mode=STANDARD

function setup()
parameter.integer("delay",1,10000)

end

function draw()
background(0)
for z=1,delay*10000 do
a=math.sqrt(z)
end
text(ElapsedTime,WIDTH/2,HEIGHT/2)
end
``````

hm, weird. tweens are easy enough, i guess i’ll go that way.

Here’s an example of executing different functions at different time intervals.

``````viewer.mode=STANDARD

function setup()
t1=checkDelay(.3)
t2=checkDelay(.5)
t3=checkDelay(1)
end

function draw()
background(0)
if t1:test() then
print(".3   ",t1.s:gettime())
end
if t2:test() then
print(".5   ",t2.s:gettime())
end
if t3:test() then
print("1.0  ",t3.s:gettime())
end
end

checkDelay=class()

function checkDelay:init(int)
self.s=require("socket")
self.start=self.s:gettime()
self.val=0
self.interval=int
end

function checkDelay:test()
if self.s:gettime()-self.start>self.val then
self.val=self.val+self.interval
return true
end
return false
end
``````