This is my first post in Community Resources, so let me know if I need to add or improve details.
Roblox Model: https://www.roblox.com/library/8644509383/TimeZoneService
GitHub: https://github.com/Eezby/Roblox-TimeZoneService
Description
Greetings developers!
This was a fun mini side project I wrote in a few hours after viewing this post about how to determine what region a Roblox server is being hosted in. This module allows you to figure out what region / time zone a server is running in as well as what time zone a client is running in. I thought of a few potentially useful use cases that I will list below.
Use Cases
-
Use alongside a matchmaking service to queue players in the same or similar time zones together. Or let them pick which time zones they prefer to be queued in.
-
Integrate with a server list system so players can see which regions a server is being hosted in. Using this module you can tell the client if a region would be a good or bad fit for them.
Functions
TimeZoneService:GetServerInfo()
Get details about the server’s location and timezone data. See notes in the function for editing data received.
TimeZoneService:GetClientTimeZone(client: Instance<Player>)
Invoke the client for their GMT time offset and receive information about their timezone.
TimeZoneService:GetTimeZoneInfo(zone: string)
Pass in a valid timezone from the TimeZone table below (ex. EST, PST, GMT) and receive information about it’s full name and offset.
TimeZoneService:GetTimeZoneByOffset(offset: number, inSeconds: boolean)
Pass in an offset and get back the corresponding timezone. You can specify whether the offset is in seconds or hours using the optional “inSeconds” boolean value.
TimeZoneService:GetTimeZoneByContinent(continent: string)
Pass in a valid continent code (NA, SA, AS, AF, EU, AU) and receive a list of timezones within that continent.
TimeZoneService:GetTimeZoneStatus(zone1: string, zone2: string)
Pass in two valid timezones from the TimeZone table below and receive information about how viable their are together. For example EST → EST is “Amazing”, while EST → GMT is “Terrible”. This can be used for telling players how their ping might fair in a certain server region.
TimeZoneService:SortBestTimeZones(zone: string)
Pass in a valid timezone from the TimeZone table below and receive an ordered list of every timezone from best to worse in terms of distance and “group”.
Examples
local TimeZoneService = require(game.ReplicatedStorage.TimeZoneService)
print(TimeZoneService:GetServerInfo())
local TimeZoneService = require(game.ReplicatedStorage.TimeZoneService)
local serverInfo = TimeZoneService:GetServerInfo()
local serverTimeZone, serverZoneInfo = TimeZoneService:GetTimeZoneByOffset(serverInfo.gmtOffset)
local clientTimeZone, clientZoneInfo = TimeZoneService:GetClientTimeZone(player)
print(serverTimeZone.." -> "..clientTimeZone..": "..TimeZoneService:GetTimeZoneStatus(serverTimeZone, clientTimeZone))
local clientTimeZone, clientZoneInfo = TimeZoneService:GetClientTimeZone(player)
print(TimeZoneService:SortBestTimeZones(clientTimeZone)) -- Example is EST
How It works
Getting The Server Time Zone: This is done using two APIs, one to get the server’s IP, and another to use that IP to get the relevant information.
Getting The Client Time Zone: This is done using the fact that workspace:GetServerTimeNow() always returns the time in terms of UTC and tick() returns the time in terms of the client’s time zone. Using this we can do tick() - workspace:GetServerTimeNow()
to get the utcOffset in seconds.
The actual function is math.floor((tick() - workspace:GetServerTimeNow()) / 100 + 0.5) * 100
Comparing this to the table of time zones I listed in the module, you can accurately find a player’s time zone.
Notes
-
The server’s region is not determined by the first player to enter. Sometimes it is, sometimes it isn’t - do not rely on the client’s time zone to guess what the server’s time zone will be.
-
I have no clue what the API limitations are, and the function weightings are completely based on my opinion.
-
More details can be seen on the GitHub page or inside the module itself
Feel free to give feedback! I hope you can mess around with this module or find a way to use it in a production level game. Thanks for reading!