NtpTime
Coding Style wiki
NtpTime is a static clock-synchronization utility for NTP servers or HTTP time APIs. After synchronizing once, it keeps providing the corrected current time (extrapolated as "time of the received response + elapsed time"), unaffected by users changing the device clock — suitable for anti-cheat, daily reset, and other scenarios that need trusted time.
| Namespace | OxGKit.TimeSystem |
| Type | public static class NtpTime |
| Source | NtpTime.cs |
using OxGKit.TimeSystem;
Quick Start
using Cysharp.Threading.Tasks;
using OxGKit.TimeSystem;
// Synchronize with an NTP server (defaults: time.google.com, 10s timeout)
await NtpTime.Synchronize();
// Read the corrected time once synchronized
if (NtpTime.IsSynchronized())
{
System.DateTime now = NtpTime.GetNow(); // local time
System.DateTime utcNow = NtpTime.GetUtcNow(); // UTC time
}
General Rules
Synchronization Methods
Synchronize picks the synchronization method automatically based on the ntpServer parameter:
| Method | ntpServer Parameter | Description |
|---|---|---|
| NTP (UDP) | A host name (e.g. time.google.com) | Requests the NTP server over a UDP socket (port 123), executed on the thread pool. |
| HTTP time API | A URL starting with http:// or https:// | Requests via UnityWebRequest (WebGL compatible); by default parses the TimeAPI.io Timezone API response format, e.g. https://timeapi.io/api/timezone/zone?timeZone=Asia/Taipei. |
Attention WebGL cannot use UDP sockets — synchronize through an HTTP time API instead (pass the API URL as ntpServer).
Behavior While Not Synchronized
Important Synchronize is an async flow — gate reads on IsSynchronized. While not synchronized, the time getters only print a warning log ([NTP] No synchronized.) and fall back to the local system time (GetTimeZone returns an empty string, GetUtcOffset returns 0) — no exception is thrown.
Time Extrapolation
Reminder After a successful sync, the "time of the received response" is recorded, and later reads are extrapolated as synchronized time + elapsed time — no repeated synchronization required; to re-correct (e.g. after the network recovers), simply call Synchronize again.
Methods
Method Overview
| Method | Description |
|---|---|
| Synchronize | Begins synchronizing with an NTP server or HTTP time API. |
| IsSynchronized | Whether synchronization has completed. |
| GetNow | Gets the corrected local time. |
| GetUtcNow | Gets the corrected UTC time. |
| GetNtpDate | Gets the corrected time in the original synchronized timezone. |
| GetTimeZone | Gets the timezone name used for synchronization. |
| GetUtcOffset | Gets the UTC offset (hours) of the synchronized time. |
Synchronize
public static UniTask Synchronize(string ntpServer = "time.google.com", int requestTimeout = 10)
public static UniTask Synchronize<TResponseFormat>(string ntpServer = "time.google.com", int requestTimeout = 10) where TResponseFormat : TimeApiResponseFormat
Begins synchronizing with an NTP server or HTTP time API (the synchronized state is reset to unsynchronized first):
ntpServer: an NTP server host name, or a time API URL starting withhttp(s)://(see Synchronization Methods).requestTimeout: request timeout in seconds (default 10); a timeout prints an error log.- The generic version specifies the deserialization format of the HTTP response (must inherit TimeApiResponseFormat).
// NTP (UDP) synchronization
await NtpTime.Synchronize();
// HTTP time API synchronization (WebGL compatible)
await NtpTime.Synchronize("https://timeapi.io/api/timezone/zone?timeZone=Asia/Taipei");
Attention When the network is unreachable (Application.internetReachability is NotReachable), a warning is printed and the call returns without synchronizing.
IsSynchronized
public static bool IsSynchronized()
Returns whether synchronization with the NTP server has completed.
GetNow
public static DateTime GetNow()
Gets the corrected local time; when the system timezone is close to the server timezone (difference under 0.1 hours), the synchronized time is returned as-is, otherwise it is converted to UTC first and then to the system local time. While not synchronized, prints a warning and returns DateTime.Now.ToLocalTime().
GetUtcNow
public static DateTime GetUtcNow()
Gets the corrected UTC time (converted using the UTC offset stored at sync time). While not synchronized, prints a warning and returns DateTime.Now.ToUniversalTime().
GetNtpDate
public static DateTime GetNtpDate()
Gets the corrected time in the original synchronized timezone (kept in the timezone it was received in, only advanced by the elapsed time). While not synchronized, prints a warning and returns DateTime.Now.
GetTimeZone
public static string GetTimeZone()
Gets the timezone name used for synchronization (e.g. Asia/Taipei, provided by the HTTP time API); returns an empty string while not synchronized.
GetUtcOffset
public static double GetUtcOffset()
Gets the UTC offset (hours) of the synchronized time; returns 0 while not synchronized.
Response Format
HTTP time API responses are deserialized with JsonUtility; the format classes are all marked [Serializable]:
public abstract class TimeApiResponseFormat { }
public class TimeApiTimezoneResponse : TimeApiResponseFormat
{
public string timeZone; // e.g. "Asia/Taipei"
public string currentLocalTime; // e.g. "2025-05-15T12:55:08.5386566"
public UtcOffset currentUtcOffset;
public UtcOffset standardUtcOffset;
public bool hasDayLightSaving;
public bool isDayLightSavingActive;
public DstInterval dstInterval;
}
Attention The built-in processing currently only supports the TimeApiTimezoneResponse (TimeAPI.io Timezone API) format — it requires the timeZone, currentLocalTime, and currentUtcOffset fields; other formats result in a parse-failure error log.