How to convert seconds into DD:HH:MM:SS format

:information_source: Attention Topic was automatically imported from the old Question2Answer platform.
:bust_in_silhouette: Asked By Help me please

Hi I have recently tried to create a countdown timer to show the time remaining for the action to occur but my way seems to be lengthy and inefficient.

var time_total = 0
var time_dict = {"D" : 0, "H" : 0, "M" : 0, "S" : 0}


func start_time(given_time):
	time_total = given_time * 3600 # into secs
	convert_time()

func convert_time():
	var time = time_total
	
	while time >= 60: # get minutes
		time -= 60
		time_dict["M"] += 1
	
	time_dict["S"] = time # rest is seconds
	
	while time_dict["M"] >= 60:
		time_dict["M"] -= 60
		time_dict["H"] += 1
	
	while time_dict["H"] >= 24:
		time_dict["H"] -= 24
		time_dict["D"] += 1
	
	print(time_dict)

is there any better way

:bust_in_silhouette: Reply From: Felipe

I tried to do something more readable:

var start_time
var duration

func set_start_time():
	start_time = OS.get_unix_time() #the time at the moment in seconds

func time_convert(time_in_sec):
	var seconds = time_in_sec%60
	var minutes = (time_in_sec/60)%60
	var hours = (time_in_sec/60)/60
	
	#returns a string with the format "HH:MM:SS"
	return "%02d:%02d:%02d" % [hours, minutes, seconds]

func elapsed_time():
	var elapsed_time = OS.get_unix_time() - start_time #actual time - start time

func get_remainnging_time():
	return duration - elapsed_time()
2 Likes

I found that using prev’s code cause the clock to flip over from 00:00:59 to 00:01:60 instead of 00:01:00, and so I added some stuff to the string creation that fixes it. Basically it just removes the extra multiples of 60 from the minutes and seconds, but hours don’t matter.

I also found that the %60 in the value for minutes isn’t needed. Also, you can just use the previous unit of time in making the other values.

func time_convert(time_in_sec):
	var seconds = time_in_sec%60
	var minutes = time_in_sec/60
	var hours = minutes/60

	#returns a string with the format "HH:MM:SS"
	return "%02d:%02d:%02d" % [hours, minutes - (60 * hours), seconds - (60 * minutes)]

If you were to include a days counter, you would want to add something similar to the hours part but with 24 instead:

func time_convert(time_in_sec):
	var seconds = time_in_sec%60
	var minutes = time_in_sec/60
	var hours = minutes/60
    var days = hours/24

    #returns a string with the format "DD:HH:MM:SS"
    return "%02d:%02d:%02d:%02d" % [days, hours - (24 * days), minutes - (60 * hours), seconds - (60 * minutes)]

And if you wanted twelve hours, you’d have to add an AM/PM var, but I don’t really wanna do that

I tried your solution @itsaboon, but it doesn’t work correctly. It flips from 00:00:59 to 00:01:-60, then to 00:02:-120 etc.
And it also doesn’t accept a number of seconds as float, which is the most common usecase when you’re counting with delta.

See here my solution that displays the timer dynamically down to a millisecond:

2 Likes

Okay yep. I am kiiinda stupid.

I didnt realize what the modulo was doing in calculating the seconds, but its basically its what the - (60 * minutes) is doing, and so its just subtracting it twice and giving you -60 and -120.

So you can use the version with modulo, in which you CAN’T use minutes = seconds/60 or hours = minutes/60, because seconds only ever goes up to 59.

You also need the modulo after the minutes calculation, for the same reasons.

In the version without modulo, you can do that, because removing the multiples of 60 occurs when constructing the string instead of when calculating the values.

In the end, you might save a few bytes of ram if you use the modulo version, but it doesn’t really matter. It does also shorten the code, so really in the end my “version” was just stupid.

So either

func time_convert(time_in_sec):
	var seconds = time_in_sec%60
	var minutes = (time_in_sec/60)%60
	var hours = time_in_sec/3600 #equivalent of x/60/60

	#returns a string with the format "HH:MM:SS"
	return "%02d:%02d:%02d" % [hours, minutes, seconds]

or

func time_convert(time_in_sec):
	var seconds = time_in_sec
	var minutes = time_in_sec/60
	var hours = minutes/3600 #equivalent of x/60/60

	#returns a string with the format "HH:MM:SS"
	return "%02d:%02d:%02d" % [hours, minutes - (60 * hours), seconds - (60 * minutes)]