How to make counter with while true?

Hello im trying to make a script for a daily discount that when 24 hours is up it ends the deal and replaces it with another.

how do i make a timer thats the same on all servers and is always counting down even when no server are on?

for example a player joins and there is 10 hours left on the clock. they rejoin the game 9 hours later and theres only 1 hour left.
unknown

heres my script:

local timeToEnd =  os.time({year=0, day=7, month = 0,hour=0, second=0})
while os.date("%X",os.time()) <= timeToEnd do
    script.parent.Text = os.date("%X",os.time())
    wait(1)
end

however i keep getting this error:
Players.SakDevRblx.PlayerGui.ScreenGui.Passes.Frame.Passes.Frame.Frame.Frame.AA.TextLabel.LocalScript:4: attempt to compare string <= nil

You’re comparing an os.date() formatted string to an os.time() constructor set for 7 days after unix epoch back in January 1970. Neither of these are good references to compare. Try instead:

local now = os.time()---get the time the server is at
local saleEnds = os.time() + 604800 --there are 604,800 seconds in one week (7 days)

repeat
	now = os.time()--update now every second
	print(os.date("%X", now))--print formatted now *but leave now in seconds*
	task.wait(1)--wait() is superseded by task.wait(), use that instead
until now == saleEnds--this will loop until os.time() is the same as your sale endpoint

print("the sale is over!")

You’ll want to adapt this logic to your plan by introducing a datastore that will save saleEnds. Whenever a live server sees that it’s changed, any of them can update it to be saleEnds + 604800 again to keep it precise.
You’re also able to define an exact time at which the timer starts, if you want it to start at a cleaner time like midnight.

i did this instead and it works but without datastore.

local dealends = game.ReplicatedStorage.EndDate.Value
local time = dealends - os.time()

while dealends ~= 0 do 
	task.wait(1)
	time = time - 1
	script.Parent.Text =  "Deal ending in: " .. os.date("%X",time) 
end```

all you have to do is write a function to convert GetRemainingTime() to readable h/m/s
(on the client)
offers.rbxl (35.8 KB)