UTC Time Function

As a Roblox developer, I notice the chaos exploiters bring to the table. My team and I found a way to add an extra wall against hacks, but we need a function that returns the current UTC time, and the result should be the same whether it’d be called in the server or client side.

Thanks.

3 Likes

You can’t trust anything coming from the client, so if you want to do something time-based you should always request the time from the server if you need to validate something.

1 Like

What’s your use case? Syncing time?

They can just spoof the function so there’s no point.

1 Like

It’s a very complicated security tool used by major corporations. We don’t really want to leak on how it works since it might be publicly seen by someone who can create the hack themselves.

if you’re loading any part of this on the client they will be able to reverse engineer it, and if you’re not it couldn’t possibly work :stuck_out_tongue:

Seems like an XY problem to me. Consider posting the original problem that you are trying to solve in the Scripting Support category (#development-support:scripting-support) instead.

You should never trust the client, exploiters can hook into API / system settings / network requests and change the value of this “UTC Time Function” as they please. It would not give you any real security, you can never trust values you get client-side. You need to do checks on the server to distinguish exploiters from legitimate players.

If no use cases are provided, the chances of a feature request being considered are very slim.

If you are really building a “security tool” (whatever that even means on Roblox), you should be able to provide an explanation as to how it works without the security being compromised. If not, you are building a “security through obscurity tool”, which isn’t real security.

7 Likes

There is already a function that returns the current time in UTC: os.time()

1 Like

Note that this is subject to system settings: if your time zone / time settings are wrong, this will still return a value that isn’t correct (which is fine, that’s intended). I think OP was attempting to ask for a time value that was automatically synced between client/server.

Ah, I see. Given that it’s reasonably safe to assume os.time called on the server is going to be correct, would it be okay to reject the client’s time if it’s x seconds out and warn the player?

Difficult to tell what OP’s trying to do here. Just throwing ideas around.

It’s fine to assume that the server’s time is correct; for the client’s time I would definitely not assume anything nor kick/warn them if their time isn’t correct. It might be wrongly configured by accident.

1 Like

If the UTC time is really needed, one could use the HttpService to do a workaround.

You can eventually use, for example, this endpoint to retrieve an approximate UTC time. Of course this has got it’s own limitations such as:

  • Endpoint availability is not guaranteed;
  • You cannot execute this from the client;
  • Execution will yield the script.

If this function was a thing, it would be most useful in the case not all servers share the same timezone.

Say that Roblox one day decides to open servers in UK - and I have a system that tells the user how long ago was the last time he joined.

Let’s say he joins in an US server, then leaves and immediately joins an UK server. Since the timezones are different, using os.time() will produce an erratic value, and the player will be told that the he didn’t join since hours ago, when in fact he just hopped servers.

If the opposite happens (UK then US), the value will be even more erratic as it would be negative. If you have a system that relies on an universal date/time, then the OP’s request would make sense to be implemented.

1 Like

In case anyone runs into this thread looking for a valid use for UTC time functions.

os.time() returns the number of seconds since the unix epoch (January 1, 1970 12:00 AM UTC). This may be different than other Lua environments you’re used to. You should call this function on the server to save timestamps for things like “last logged on”.

On the client, you should call os.date("*t", some_time_value) to get a table containing the year/month/day/etc for the value that os.time() returned. The reason you should do this on the client is because the *t option uses the client’s local timezone, as opposed to the !*t option which will show the UTC date for the given timestamp.

For example:

local function pretty_date(date)
    local dateString = "{year}-{month}-{day} {hour}:{min}"
    local result = string.gsub(dateString, "{(%w+)}", date)
    return result
end

-- the time I wrote this was May 18, 2018 11:48 AM PDT, these values will obviously be different.
local now = os.time() -- roughly 1526668592
print(pretty_date(os.date("*t", now))) -- 2018-5-18 11:48, this is the local time
print(pretty_date(os.date("!*t", now))) -- 2018-5-18 18:48, this is as a UTC date

If you need the UTC time on the client for exploit mitigation, you may as well use os.time(). Any mechanism that we add into the engine would be possible to exploit just as easily as if you added a RemoteEvent that fires every second with the current time. Nothing on the client can ever be trusted, you should do as much mitigation on the server as possible and only use client-sided mitigations once you’ve already done everything else you can.

Edit (May 2021): Some time after this post was written, the DateTime API was introduced. I recommend using that for new work instead of os.time/os.date.

32 Likes

If revealing how it’s done would easily allow it to be countered then it doesn’t seem like it’s that great.

2 Likes

Yes, but that’s the current time in the system. It is dependent on your machine’s configurations; ie. if you change your time locally, os time will return a different value.

Httpservice could be a valid solution, however, if the external API dies, the game will also break. It’s too risky.

That’s what I have pointed out already: