The translation
Every path here follows the same structure as the rest of the API, one name per resource with its arguments in the path, so WorldTimeAPI's paths map to ours rather than repeating them:
| WorldTimeAPI | Here | Answer |
|---|---|---|
http://worldtimeapi.org/api/timezone/Europe/Oslo | https://aisenseapi.com/services/v1/datetime/Europe/Oslo | The fields for that zone |
http://worldtimeapi.org/api/timezone/America/Argentina/Buenos_Aires | https://aisenseapi.com/services/v1/datetime/America/Argentina/Buenos_Aires | Three-part names work the same way |
http://worldtimeapi.org/api/ip | https://aisenseapi.com/services/v1/ip_datetime | The fields where your address is |
http://worldtimeapi.org/api/ip/8.8.8.8 | https://aisenseapi.com/services/v1/ip_datetime/8.8.8.8 | The fields where that IPv4 or IPv6 address is |
http://worldtimeapi.org/api/timezone | https://aisenseapi.com/services/v1/timezones | Every zone, as objects with timezone and offset |
http://worldtimeapi.org/api/timezone/Europe | https://aisenseapi.com/services/v1/timezones | The same list; keep the names that start with Europe/ |
Any .txt form | None | Every answer is JSON |
curl https://aisenseapi.com/services/v1/datetime/Europe/Oslo{
"datetime": "2026-10-03T12:41:07+02:00",
"timezone": "Europe/Oslo",
"abbreviation": "CEST",
"utc_offset": "+02:00",
"dst": true,
"unixtime": 1791024067,
"raw_offset": 3600,
"dst_offset": 3600,
"dst_from": "2026-03-29T01:00:00+00:00",
"dst_until": "2026-10-25T01:00:00+00:00",
"day_of_week": 6,
"day_of_year": 276,
"week_number": 40,
"utc_datetime": "2026-10-03T10:41:07+00:00"
}One more change is not optional: this host answers HTTPS only. A sketch that fetched http://worldtimeapi.org over a plain WiFiClient has to use https:// and a WiFiClientSecure, shown below.
What differs
- No
client_ip. Every other WorldTimeAPI field is there with the same name and type./ip_datetimeanswersipfirst, the address it looked up. - Whole seconds.
datetimeandutc_datetimeend at the second, without the microseconds WorldTimeAPI added. ISO 8601 parsers read both forms. - Key order. The keys start with
datetimeandtimezonerather than in alphabetical order. A JSON parser does not care; code that matched the raw text line by line does. - The zone list.
/timezonesanswers{"timezones": [{"timezone": "Europe/Oslo", "offset": "+0200"}, ...]}, with each zone's offset right now, rather than a plain list of names, and has no per-area form. - Errors in our words. An unknown zone is HTTP 400 here, where WorldTimeAPI answered 404. The table under Errors has each case.
The fields
| Field | Type | Meaning |
|---|---|---|
| datetime | string | Local date and time, ISO 8601 to the second with the offset. |
| timezone | string | The zone name in its usual case. Names match in any case, and old names such as Europe/Kiev are accepted. |
| abbreviation | string | The local abbreviation, such as CEST, EDT or IST, or a numeric one such as -03 where the database has no letters. |
| utc_offset | string | The offset in force now, as +HH:MM, summer time included. |
| dst | boolean | Whether summer time is in force. |
| unixtime | integer | Seconds since 1970-01-01 UTC. |
| raw_offset | integer | The standard offset from UTC in seconds, without summer time. |
| dst_offset | integer | Seconds summer time adds now: 3600 almost everywhere, 1800 on Lord Howe Island, 0 outside summer time. The zone database counts Irish winter time and Moroccan Ramadan time as summer time with a negative offset, so it is -3600 there and then. |
| dst_from | string or null | When the current summer time period began, in UTC. null when dst is false. |
| dst_until | string or null | When it ends, in UTC. null when dst is false. |
| day_of_week | integer | 0 for Sunday to 6 for Saturday. |
| day_of_year | integer | Local day of the year, starting at 1. |
| week_number | integer | The ISO 8601 week. |
| utc_datetime | string | The same moment in UTC, ending in +00:00. |
| ip | string | On /ip_datetime only, and first: the address looked up. |
Slashes in zone names are not escaped, so code that looks for Europe/Oslo in the body as text still finds it. raw_offset + dst_offset is always the offset in force.
On an ESP32
The usual sketch called http.begin("http://worldtimeapi.org/api/timezone/Europe/Oslo"). Over HTTPS the call takes a secure client. This short example skips certificate verification. The connection is encrypted, but the server is not authenticated and the time could be forged. Use CA certificate verification when your application needs to trust the returned time:
#include <WiFiClientSecure.h>
#include <HTTPClient.h>
WiFiClientSecure client;
client.setInsecure(); // or client.setCACert(...) to check the certificate
HTTPClient http;
http.begin(client, "https://aisenseapi.com/services/v1/datetime/Europe/Oslo");
int code = http.GET();
String body = http.getString();
http.end();Parsing does not change for the fields the sketch already reads, unless it read client_ip or expected a fraction of a second in datetime. For an ESP8266 the class is BearSSL::WiFiClientSecure with the same setInsecure().
Errors
| Case | Status | Body |
|---|---|---|
| Unknown zone | 400 | {"error":"Unknown time zone.","fix":"..."} |
| Address with no zone found | 404 | {"error":"No time zone is known for this address.","fix":"..."} |
| Not an IPv4 or IPv6 address | 400 | {"error":"Invalid IP address.","fix":"..."} |
| Over 5000 calls from one address in a day | 429 | With Retry-After until midnight Oslo time |
The fix says what to send instead. A client that treated WorldTimeAPI's 404 as "unknown zone" checks for 400 here.
Where the answers come from
Zone names and their rules come from the IANA time zone database bundled with the server, which is updated with its releases. The zone of an address comes from an address lookup. Each server worker keeps lookup results in memory, keyed by IP address. A result is reused for up to an hour, or ten minutes when no zone was found. Expired entries can stay in memory until replaced, removed to make room, or the worker restarts. Not every address has a zone; one without answers 404 rather than a guess, and asking by zone name is the way around it. Requests are logged with the caller's IP address and URL path, as well as status and response time.
A device that knows its zone does better to ask /datetime/{zone} than /ip_datetime: the answer is the same, and no lookup is involved.
Privacy and limits
The address in /ip_datetime/{ip} is held in the memory cache and can also appear in request logs. See our privacy policy for log retention. IP-based time zones are approximate and may differ from the device's location.
Every path shares the service-wide ceiling of 5000 requests per IP address per day. No key, no account and no sign-up. The whole catalogue is on Free public REST APIs.