Accurately getting player's local time?

I have tried multiple methods of getting player’s local time but all of which seem to based on the time on the player’s device which the player can modify easily. Is there a way to get around this?

I’m trying to make a daily mission system that resets at the end of the player’s day.

1 Like

Maybe u can use datastores to make it so that you can get the UTC time or something when they joined and claimed the reward and when they join back calculate how much it had been since they had last joined. If it’s 24 hours or more then reset it.

There is no foolproof method. You can use LocalizationService and map regions based on time, but that’s bypassable as well.

Why not just store the UTC reset time on the server side? You can also give players the option to decide (and possibly lock) when their daily resets.

yea but that’s not what I’m trying to achieve though… I’m trying to make it reset at the end of the player’s day.

Theres no foolproof way to do this (since vpns and stuff literally exist), but perhaps take a try with localization service? (you can get the country of the player, which you can then use to find the timezone)

To get the players local time you just need to call… local localTime = os.date(“*t”).
The only real “trick” to this is to call that from a local (client) script.

Ran accross some gold for ya, a tutorial by AlvinBlox.
How To Make A Daily Reward - Roblox Scripting Tutorial

If the client is determined enough, they can always find ways to hide their actual date and time. To make sure that they aren’t able to receive a reward unless a day has passed, you’ll need to check the time on the server-side, which you can do so as follows:

local DataStoreService = game:GetService("DataStoreService")
local Players = game:GetService("Players")
local RunService = game:GetService("RunService")

local dataStore = DataStoreService:GetDataStore("Example")


local canSave = {}


Players.PlayerAdded:Connect(function(player)
	local success, data = pcall(dataStore.GetAsync, dataStore, player.UserId)

	if success then
		canSave[player] = true

		if data then
			if (DateTime.now().UnixTimestamp - data.Time) >= 86400 then -- 86400 is 1 day in seconds
				-- A day has passed since this player joined the game
			else
				-- Not enough time has passed for the daily reward
			end
		else
			-- Handle logic for first-time player
		end
	else
		warn(`Failed to get data for Player {player.UserId} ({player.DisplayName})\nError: {data}`)
	end
end)

local function saveData(player)
	if canSave[player] then
		canSave[player] = nil

		local data = {
			Time = DateTime.now().UnixTimestamp -- Save the current time at the moment the player leaves the game
		}

		local success, error = pcall(dataStore.SetAsync, dataStore, player.UserId, data)
		if success then return end

		warn(`Failed to save data for Player {player.UserId} ({player.DisplayName})\nError: {error}`)
	end
end

Players.PlayerRemoving:Connect(saveData)

game:BindToClose(function()
	if RunService:IsStudio() then
		task.wait(1)
	else
		local x, y = 0, 0

		for _, player in Players:GetPlayers() do
			x += 1

			task.spawn(function()
				saveData(player)

				y += 1
			end)
		end

		repeat task.wait() until y == x
	end
end)

A possible solution is to use the Roblox game’s internal clock, which is synchronized across all players. You can access this internal clock using the game:GetService("Clock") API.

Here’s an example of how you can use the internal clock to determine the player’s day:


local ClockService = game:GetService("Clock")

-- Get the player's local time
local playerTime = game.Players.LocalPlayer.ClockTime

-- Get the internal clock's current time
local internalTime = ClockService:GetTime()

-- Calculate the difference between the two times
local timeDifference = internalTime - playerTime

-- If the time difference is greater than a certain threshold (e.g., 24 hours), reset the player's daily mission progress
if timeDifference > 86400 then
    -- Reset daily mission progress here
end

This code gets the player’s local time and the internal clock’s current time, then calculates the difference between the two. If the difference is greater than 24 hours (86400 seconds), it resets the player’s daily mission progress.

Note that this method is more secure than relying on the player’s local time, as it’s harder for players to modify the internal clock. However, it’s not foolproof, as a player could potentially exploit a bug or glitch in the game’s clock system.

Also, keep in mind that this method only works if the game is running on a Roblox server that supports the ClockService API.

You can use client time to determine the next reward time and UTC time as a 24 hour minimum timer so clients cannot get an award early. Only issue is this will prevent roaming players from getting an award when they legimately move to a time zone that’s in the future :sparkles: past that reward timestamp.

Clock service is not even real.

Man stop using AI, it fakes functions and services that doesn’t exist.