My mistake, os.time()doesn’t return the time in the local timezone (though still possibly early/late on the client)
(Also the Roblox staff said that you should use the DateTime API instead)
So basically you could either do:
Send the end time to the client
(But if the client’s clock is ahead or behind the timer will be aswell)
Send the remaining amount of time to the client
(But the timer will be behind by the amount of ping the client has)
(You could try to get around this by removing the ping from the remaining time, but it will never be perfectly accurate)
The result of os.time() is based on the device’s local clock. They are usually in sync within a few seconds because most OSes by default synchronize their clock over the internet. This isn’t 100% reliable though. For example, anyone can go into their time and date settings and manually change the current date of their OS.
For truly synchronized time between client and server, you can use Workspace:GetServerTimeNow() instead. This API tries to be very tightly synchronized, and has microsecond granularity.
The returned value of GetServerTimeNow is a unix timestamp, similar to os.time(). So to turn it into a human readable date you can pass it into existing APIs like DateTime.fromUnixTimestamp and os.date()