how do I make a timer display in minutes, seconds and milliseconds?

Godot Version

4.3

Question

`Hey people. I’m busy developing a 2D platformer game and need help with a timer. I want it to count up to 10 minutes with a format of 00:00:00, kinda like Sonic, but I don’t know how to program it in. Here’s my current code (it counts down from 60 seconds):

extends Node2D

var label=Label
var time=Timer
# Called when the node enters the scene tree for the first time.
func _ready() -> void:
	label = $CanvasLayer/Label2
	time = $CanvasLayer/Timer
	
	time.start()


# Called every frame. 'delta' is the elapsed time since the previous frame.
func _process(_delta: float) -> void:
	update_label_text()
	
func update_label_text():
	label.text = str(ceil(time.time_left))

`

It’s a simple division.

time_left is expressed in seconds and is a float. Figure out how many full minutes you can fit inside that amount of time. For instance, if time_left is 179.01, you know you can fit two periods of 60 seconds in it because: 179.01 - (2 * 60) = 59.01.

The remainder (59.01) is shorter than a full minute, but you can still get 59 seconds out of it: 59.01 - (59 * 1) = 0.01.

The remainder after division (0.01) is shorter than a second, but can still fit 10 ms because 0.01 - (10 * 0.001) = 0.

That gives two minutes, 59 seconds, and 10 ms. All that remains is to display that time in your label.

Here is an example using a timer node:

extends Node2D

# Timer variables
var time_passed: int = 0 

func _ready() -> void:
	start_timer()

func start_timer() -> void:
	var timer: Timer = Timer.new()
	timer.wait_time = 1.0
	timer.one_shot = false
	timer.autostart = true
	timer.timeout.connect(_on_timer_timeout)
	add_child(timer)


func _on_timer_timeout() -> void:
	time_passed += 1
	print(get_converted_time(time_passed))


func get_converted_time(time: int) -> String:
	var minutes: int = floori(time / 60.0)
	var seconds: int = time % 60
	return "%02d:%02d" % [minutes, seconds]

Here is an example just using delta:

extends Node2D

var timer_running: bool = false
var real_time: float
var time_passed: int
var display_time: int


func _ready() -> void:
	start_timer()


func start_timer() -> void:
	real_time = 0
	time_passed = 0
	display_time = 0
	timer_running = true


func _process(delta: float) -> void:
	if timer_running:
		real_time += delta
		if real_time > 1:
			real_time -= 1
			time_passed += 1
			print(get_converted_time(time_passed))


func get_converted_time(time: int) -> String:
	var minutes: int = floor(time / 60.0)
	var seconds: int = time - minutes * 60
	var time_string: String = "%02d:%02d" % [minutes, seconds]
	return time_string

Did you want minutes, seconds and milliseconds? You can probably guess how to do it from the above. I actually think using delta is more accurate but using the timer node is more efficient (I think).

Hope that helps.