Guides

Show the right business hours based on visitor location

"We're open until 6pm" is only useful if the visitor reading it knows which 6pm you mean. A visitor in a different time zone from your business needs that comparison done in their own local time, not yours.

Getting the visitor's time zone

A single IP lookup returns a timezone field directly, giving you what you need without a separate call.

GET /v1/ip?ip=203.0.113.44
{
  "status": "ok",
  "ip": "203.0.113.44",
  "version": 4,
  "found": true,
  "country": "Japan",
  "country_code": "JP",
  "region": "Tokyo",
  "city": "Tokyo",
  "postcode": "100-0001",
  "lat": 35.6762,
  "lon": 139.6503,
  "timezone": "Asia/Tokyo",
  "asn": 2345,
  "org": "Example Telecom"
}

Comparing against your business hours

Convert your own business hours, stored against your business's own time zone, into the visitor's zone using the timezone identifier you just retrieved, then compare against the visitor's current local time to decide whether to show "open now" or "closed" along with the local time you are showing it as of.

A second example: a business with more than one location

A business with locations in different cities should look up each location's own posted hours against its own stored zone, then compare each separately against the visitor's zone, rather than assuming one set of hours applies everywhere. This matters most when a visitor is comparing two locations on the same page, since one might read as open and the other closed at the exact same moment if they sit in different zones or observe daylight saving differently.

Being explicit about which time zone you mean

Rather than silently converting and hoping the visitor understands, show both pieces clearly, something like "Currently closed. Opens at 9am your time (Asia/Tokyo)." Being explicit avoids confusion when a business operates across a boundary that shifts with daylight saving on one side but not the other.

A common mistake to avoid

Do not compute the open or closed comparison once and cache that boolean result for the rest of the visitor's session. A comparison made at 5:55pm will read "open" and stay wrong by 6:05pm if the underlying open state is cached rather than recalculated. Cache the visitor's time zone identifier, since that is genuinely stable for a session, but recompute the actual open or closed comparison fresh on every render.

An edge case: zones that do not observe daylight saving

Some regions keep a fixed offset year-round while a neighboring region shifts twice a year, which means the gap between two zones is not constant across the calendar. If your comparison logic hard-codes an offset in hours rather than working from the timezone identifier and letting your date library handle the conversion, it will drift out of sync for exactly the weeks around a daylight saving change.

Caching the zone, not the open state

The visitor's time zone identifier is stable for a session and worth caching. Whether the business is currently open changes throughout the day, so recompute that comparison at render time using the cached zone rather than caching the open or closed state itself.

Checking a specific past or future moment

If you need to know what the offset was, or will be, at a specific moment rather than right now, such as confirming what time an order placed yesterday actually was in the customer's zone, /v1/timezone accepts an optional time parameter as a unix timestamp for exactly that kind of historical or future check.

Request cost

One IP lookup per new visitor session covers this feature. That is a single request cached for the length of the visit, keeping a busy storefront site well within the 2,500 free requests a day included with every key.

Getting "open now" right for a global audience is a matter of one lookup and a straightforward time comparison, not a complicated feature. The IPv4 lookup docs list the full response shape.