Is there any way to get the exact millisecond of now in UTC from a server?

Is there any way to get the millisecond of now, from the server in Universal Coordinated Time?
I know tick() exists but that gets the local timezone instead of UTC and os.time() doesn’t get the millisecond.
Something like C#'s DateTimeOffset.UtcNow.ToUnixTimeMilliseconds()

using System;
					
public class Program
{
	public static void Main()
	{
		Console.WriteLine(DateTimeOffset.UtcNow.ToUnixTimeMilliseconds());
	}
}

1586987617292

1 Like

1 second = 1000 milliseconds

So do os.time()*1000

1 Like

I want the exact millisecond, this has the same problem.
os.time() * 1000 is basically doing DateTimeOffset.UtcNow.ToUnixTimeSeconds() * 1000 which isn’t what I’m looking for

using System;
					
public class Program
{
	public static void Main()
	{
		Console.WriteLine(DateTimeOffset.UtcNow.ToUnixTimeSeconds() * 1000);
		Console.WriteLine(DateTimeOffset.UtcNow.ToUnixTimeMilliseconds());
	}
}

1586988139000
1586988139913

See the difference? May not look a lot, but to me, it does.

I do not understand. os.time returns seconds. You multiply by 1000 to get milliseconds. The difference should not affect your code.

os.time returns only whole number seconds. This is not what @Blockzez is looking for.

As for the OP, your best bet would be adding on local milliseconds like so: os.time() + tick()%1. The mod 1 bit essentially gets “only the decimal value.” You can’t expect milliseconds to always be accurate across Roblox, so less than a second off isn’t too bad.

11 Likes
local offset = os.time() - tick()
function GetTime()
	return tick() + offset
end

GetTime will return UTC time with the same precision as tick(). It will be off by at most 1 second from actual UTC, due to the difference in precision between os.time() and tick().

8 Likes

Ok, but wouldn’t HttpService also work?
Web server:

await context.Response.WriteAsync(DateTimeOffset.UtcNow.ToUnixTimeMilliseconds().ToString());

Roblox ServerScriptService:

local HttpService = game:GetService("HttpService");
local current_ms = HttpService:GetAsync("https://localhost:44382/", true);
print(current_ms);

1586989969144

as opposed to:

print((os.time() * 1000) + math.floor((tick() * 1000) % 1000));

1586989969234

but the percision of both is different, which one is more percise?

The problem is latency. By the time you get the response, the reported time will be out of sync by however long it took for the response to be received. There are techniques like NTP for synchronizing clocks, but that’s mostly likely overkill for your use-case.

7 Likes

Maybe this is a better version of that since timezones are separated in hours right?

local function RoundNumber(Num,RoundNum)
   return math.floor((Num/RoundNum)+.5)*RoundNum
end
local TimeOffset=RoundNumber(os.time()-tick(),3600)
local function GetTime()
	return tick()+TimeOffset
end

edit: There are some timezones that are not separated by hours, just change the number 3600 to 900

local function RoundNumber(Num,RoundNum)
   return math.floor((Num/RoundNum)+.5)*RoundNum
end
local TimeOffset=RoundNumber(os.time()-tick(),900)
local function GetTime()
	return tick()+TimeOffset
end

I did not test it though.

1 Like

@Blockzez I am guessing 4 months later this is no longer an issue. I’m just trying to help others >->.

4 Likes

ik this post is old but have you tried os.clock()?

DateTime.now().UnixTimestampMillis