Timezone Detection
Automatically detect user timezones from city data for scheduling and localization.
Overview
Locality API returns IANA timezone identifiers (e.g., "Asia/Dubai", "America/New_York") for every city. This enables accurate timezone detection without relying on browser APIs, which can be spoofed or inaccurate.
Use cases
Scheduling apps, event platforms, e-commerce shipping estimates, personalized greetings, and time-sensitive notifications.
Getting Timezone from City
When you search for or retrieve a city, the response includes a timezone field.
json
// Response from /v1/search?q=Dubai
{
"results": [
{
"id": 292223,
"name": "Dubai",
"country": "AE",
"country_name": "United Arab Emirates",
"admin1": "Dubai",
"lat": 25.2048,
"lng": 55.2708,
"timezone": "Asia/Dubai",
"population": 3331420,
"type": "city"
}
],
"count": 1,
"query_ms": 8
}Implementation
// Get timezone from user's selected city
async function getTimezoneForCity(cityId: number): Promise<string> {
const response = await fetch(
`https://api.localityapi.com/v1/city/${cityId}`,
{
headers: { 'X-API-Key': process.env.LOCALITY_API_KEY! }
}
)
const city = await response.json()
return city.timezone // e.g., "Asia/Dubai"
}
// Convert time to user's timezone
function formatTimeInTimezone(date: Date, timezone: string): string {
return new Intl.DateTimeFormat('en-US', {
timeZone: timezone,
hour: 'numeric',
minute: '2-digit',
hour12: true
}).format(date)
}
// Example usage
const userTimezone = await getTimezoneForCity(292223) // Dubai
const now = new Date()
console.log(`Local time in Dubai: ${formatTimeInTimezone(now, userTimezone)}`)
// Output: "Local time in Dubai: 8:30 PM"Scheduling Across Timezones
When building scheduling apps, store times in UTC and convert to the user's timezone for display.
typescript
// Store user's timezone preference (from their city selection)
interface UserProfile {
id: string
cityId: number
timezone: string // "Asia/Dubai"
}
// Schedule a meeting
async function scheduleMeeting(
organizerTimezone: string,
participantTimezones: string[],
proposedTime: Date
) {
// Show proposed time in all participants' timezones
const formatter = (tz: string) => new Intl.DateTimeFormat('en-US', {
timeZone: tz,
weekday: 'short',
month: 'short',
day: 'numeric',
hour: 'numeric',
minute: '2-digit',
timeZoneName: 'short'
})
console.log('Meeting time by timezone:')
console.log(` Organizer (${organizerTimezone}): ${formatter(organizerTimezone).format(proposedTime)}`)
for (const tz of participantTimezones) {
console.log(` Participant (${tz}): ${formatter(tz).format(proposedTime)}`)
}
}
// Example: Schedule meeting at 2pm Dubai time
const meetingTime = new Date('2024-03-15T14:00:00+04:00')
await scheduleMeeting(
'Asia/Dubai',
['America/New_York', 'Europe/London', 'Asia/Tokyo'],
meetingTime
)
// Output:
// Meeting time by timezone:
// Organizer (Asia/Dubai): Fri, Mar 15, 2:00 PM GST
// Participant (America/New_York): Fri, Mar 15, 6:00 AM EST
// Participant (Europe/London): Fri, Mar 15, 10:00 AM GMT
// Participant (Asia/Tokyo): Fri, Mar 15, 7:00 PM JSTTimezone-Aware Greetings
typescript
function getGreeting(timezone: string): string {
const hour = parseInt(
new Intl.DateTimeFormat('en-US', {
timeZone: timezone,
hour: 'numeric',
hour12: false
}).format(new Date())
)
if (hour >= 5 && hour < 12) return 'Good morning'
if (hour >= 12 && hour < 17) return 'Good afternoon'
if (hour >= 17 && hour < 21) return 'Good evening'
return 'Good night'
}
// Usage with city data
async function greetUser(cityId: number, userName: string) {
const city = await fetch(`/api/locality/city/${cityId}`).then(r => r.json())
const greeting = getGreeting(city.timezone)
return `${greeting}, ${userName}! 👋`
}
// Output at 10am Dubai time: "Good morning, Ahmed! 👋"Best Practices
- Store IANA identifiers — Always store "Asia/Dubai", not "+04:00". IANA handles DST automatically.
- Store times in UTC — Convert to user's timezone only for display.
- Cache timezone data — Timezone rarely changes; cache it with user profile.
- Show timezone context — Display timezone abbreviation (PST, GST) alongside times.