How would I make a timer that is formatted in MM:SS:MS?

I found a time formatter here that I am trying to use to create a minutes:seconds:milliseconds timer. However, I cannot seem to figure out the correct method for doing it.

For more info, this is an example of what I’d like:

  1. Input time in seconds. For example, 180 seconds.
  2. Function automatically formats to MM:SS:MS (03:00:00)
  3. Timer can count down in milliseconds using a loop. (03:00:00 → 02:59:99 and so on)

This is the current format that I have:

local function FormatTimer(seconds)
	return string.format("%02d:%02d:%02d", seconds/60, seconds%60, seconds*60%60)
end

When the function is ran through a loop, the timer is stuck and does not update.
(The print function is meant to print the current timer every time it is updated. As you can see, it doesn’t update at all and stays stuck at 03:00:00.)

image

If necessary, here is the code for the loop too.

for i = timer,0,-0.01 do -- "timer" is defined through a separate function that triggers the loop to begin.
	Timer.Text = FormatTimer(timer) -- Format the TextLabel's timer.
	print(FormatTimer(timer)) -- Print the timer that is also on the TextLabel.
	task.wait(0.01)
end

Any tips would be greatly appreciated.

9 Likes

You have to put in “i” instead of timer

Timer.Text = FormatTimer(i)

5 Likes

That fixed the loop error, but now the timer doesn’t count down correctly.

RobloxStudioBeta_ujtQAEVWwq

5 Likes

heres a quick function i made dont know if it works

local function formatTime(seconds)
	local min = math.floor(seconds / 60)
	local sec = seconds % 60
	local ms = string.split(tostring(seconds),".")[2]
	if ms == nil then
		ms = "00"
	end
	ms = ms:sub(1,2)
	return string.format("%02i:%02i:%02i", min, sec, ms)
end
print(formatTime(123.345)) --02:03:34

then u can do this

for i = timer,0,-0.01 do
	Timer.Text = formatTimer(timer)
	print(formatTime(i))
	task.wait(0.01)
end
4 Likes

This timer seems to count down a bit slowly. Is there a way to address that?

RobloxStudioBeta_eAvdyoE3PE

4 Likes

task.wait() resumes on next heartbeat so don’t even bother on trying to wait .01 seconds. Ever tried using RunService instead?

3 Likes

tick()

2 Likes

I don’t use tick often so I never really thought about it.

2 Likes

are you sure its going slow? to check do this:

local start = tick()
for i = timer,0,-0.01 do
	Timer.Text = formatTimer(timer)
	task.wait(0.01)
	print( tick()-start )
end

now check if every time it prints the time it really waits .01 or slower

2 Likes

It still counts slightly slower than I’d like it to… not sure what do do from here.

1 Like

Dude really just ignored the fact that
task.wait(0.01)
resumes after a heartbeat
(so like 0.016 seconds for 60 heartbeat)

1 Like

i made a system that counts the delay between the beggining and end and subtracts that so its perfectly timed (i tested it and it works normal speed)

local runService = game:GetService("RunService")

local timer = 300
local index = timer
repeat
	local start = tick()
	Timer.Text = formatTimer(index)
	print(formatTime(index))
	runService.Stepped:Wait() --if ur in a local script set it to render stepped
	index -= tick() - start
	if index <= 0 then
		Timer.Text = formatTimer(0)
		print(formatTime(0))
		break
	end
until nil
2 Likes

if u used this before u saw this msg i made a typo so try it again

1 Like

Thanks a bunch. I appreciate the help from everyone who responded.

2 Likes

for anyone wondering heres the full script

local function formatTime(seconds)
	local min = math.floor(seconds / 60)
	local sec = seconds % 60
	local ms = string.split(tostring(seconds),".")[2]
	if ms == nil then
		ms = "00"
	end
	ms = ms:sub(1,2)
	return string.format("%02i:%02i:%02i", min, sec, ms)
end

local runService = game:GetService("RunService")

local timer = 300
local index = timer
repeat
	local start = tick()
	Timer.Text = formatTimer(index)
	print(formatTime(index))
	runService.Stepped:Wait() --if ur in a local script set it to render stepped
	index -= tick() - start
	if index <= 0 then
		Timer.Text = formatTimer(0)
		print(formatTime(0))
		break
	end
until nil
2 Likes

updated version (cleaner)

local function formatTime(seconds)
	seconds = tonumber(seconds)

	if seconds == nil then return end

	local min = math.floor(seconds / 60)
	local sec = seconds % 60
	local ms = string.format("%.2f",tostring(seconds % 1)):sub(3,4)

	return string.format("%02i:%02i:%02i", min, sec, ms)
end

the other cleaner version i sent had a typo

1 Like

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.