TextLabel Text won't change and Error occurs when seconds become 0

  1. What do you want to achieve?

I’m trying to make a timer stored in a DataStoreService and the timer is stated in the TextLabel

  1. What is the issue?
    TextLabel won’t change with no errors and when the seconds become 0, an error occurs.

I couldn’t find any problems or solutions to this, so please help me!

Code
local StarterGui = game:GetService("StarterGui")
local Players = game:GetService("Players")
local RunService = game:GetService("RunService")
local DataStoreService = game:GetService("DataStoreService")
local CountdownTesting = DataStoreService:GetDataStore("CountdownTestingg")
local Gui = StarterGui.CountdownGui
local TextLabel = Gui.TextLabel
local totalweight = 0

local itemTable = {
	percentageRarity = {70, 20, 9, 1},
	items = {
		{
			name = math.random(1,10);
			rarity = "Common";
		},
		{
			name = math.random(50,99);
			rarity = "Uncommon";
		},
		{
			name = math.random(100, 500);
			rarity = "Rare";
		},
		{
			name = math.random(1000000, 5000000);
			rarity = "Legendary";
		}
	}
}

local function SecondsToString(seconds)
	local days = math.floor(seconds / 86400)
	local hours = math.floor(seconds % 86400 / 3600)
	local minutes = math.floor(seconds % 3600 / 60)
	seconds = math.floor(seconds % 60)
	if days >= 1 and hours >= 1 and minutes >= 1 and seconds >= 1 then
		return string.format("%d days, %02d hours, %02d minutes, %02d seconds", days, hours, minutes, seconds)
	elseif days <= 0 and hours >= 1 and minutes >= 1 and seconds >= 1 then
		return string.format("%d hours, %02d minutes, %02d seconds", hours, minutes, seconds)
	elseif days <= 0 and hours <= 0 and minutes >= 1 and seconds >= 1 then
		return string.format("%d minutes, %02d seconds", minutes, seconds)
	elseif days <= 0 and hours <= 0 and minutes <= 1 and seconds >= 1 then
		return string.format("%d seconds", seconds)
	end
end

local function onPlayerAdded(player)
	for _, v in ipairs(itemTable.percentageRarity) do
		totalweight = totalweight + v
	end

	local at = math.random() * totalweight

	for key, v in pairs(itemTable.percentageRarity) do
		if at < v then
			
			local countdowntimer = itemTable.items[key].name
			print(countdowntimer)
			
			local success, value = pcall(CountdownTesting.SetAsync, CountdownTesting, "TimeLeft", os.time() + countdowntimer)
			
			local successs, valuee = pcall(CountdownTesting.GetAsync, CountdownTesting, "TimeLeft")
			if successs == false then return end
			
			while true do
				local deltaTime = valuee - os.time()
				if deltaTime > 0 then
					print(SecondsToString(deltaTime))
					TextLabel.Text = SecondsToString(deltaTime)		
				end
				if deltaTime <= 0 then
					print("works")
				end
				task.wait(1)
			end
		break
		end
		at = at - v
		end

end

Players.PlayerAdded:Connect(onPlayerAdded)
1 Like

Can you show line 70 please, as it will help solve your error.

1 Like

Line 70 is:
TextLabel.Text = SecondsToString(deltaTime)

1 Like

I unfortunately still need help with this…

This is happening because in your function SecondsToString, you pass in the seconds of 60, and then the 4th line in that function you modify that variable to 0 because of how the math works. You also set a Minute variable before hand successfully to 1

You’re getting a return of nil, so you need to specify another if statement to clarify what to do in that situation…

local function SecondsToString(seconds)
	local days = math.floor(seconds / 86400)
	local hours = math.floor(seconds % 86400 / 3600)
	local minutes = math.floor(seconds % 3600 / 60)
	seconds = math.floor(seconds % 60)
	if days >= 1 and hours >= 1 and minutes >= 1 and seconds >= 1 then
		return string.format("%d days, %02d hours, %02d minutes, %02d seconds", days, hours, minutes, seconds)
	elseif days <= 0 and hours >= 1 and minutes >= 1 and seconds >= 1 then
		return string.format("%d hours, %02d minutes, %02d seconds", hours, minutes, seconds)
	elseif days <= 0 and hours <= 0 and minutes >= 1 and seconds >= 1 then 
		return string.format("%d minutes, %02d seconds", minutes, seconds)
	elseif days <= 0 and hours <= 0 and minutes >= 1 and seconds <= 0 then
		return string.format("%d minute", minutes)
	elseif days <= 0 and hours <= 0 and minutes <= 1 and seconds >= 1 then
		return string.format("%d seconds", seconds)
	end
end;

Edit:

I wanted to give you another way to write your code that may make it easier to read

local function SecondsToString(seconds)
	local days = math.floor(seconds / 86400)
	local hours = math.floor(seconds % 86400 / 3600)
	local minutes = math.floor(seconds % 3600 / 60)
	seconds = math.floor(seconds % 60)
	local rtrn = ""
	if days >= 1 then
		rtrn = rtrn.. string.format("%d day".. if days >1 then "s" else "", days)
	end
	if hours >= 1 then
		rtrn = rtrn.. string.format((if rtrn ~= "" then ", " else "").."%02d hour".. if hours >1 then "s" else "", days)
	end
	
	if minutes >= 1 then
		rtrn = rtrn.. string.format((if rtrn ~= "" then ", " else "").."%02d minute".. if minutes>1 then "s" else "", minutes)
	end
	
	if seconds >1 then
		rtrn = rtrn.. string.format((if rtrn ~= "" then ", " else "").."%d second".. if seconds>1 then "s" else "", seconds)
	end
	return rtrn
end;

There could be an even easier way to write and read it, but all of those if statements can add confusion, and if there was another situation like you already experienced, this solution should handle it

2 Likes

Oh my god, thank you so much!! but, I also have a problem with changing the TextLabel. It just won’t work for some reason…

P.S. The first code worked perfectly but the second code doesn’t work efficiently.

BTW make sure to mark his post as solution, also sorry I didn’t see this until now