Moment.js is 67KB. Luxon is better but still a dependency. For timezone conversion in a global app, you might not need either — here's how an API solves it without client-side code.
The Problem with Client-Side Timezone Handling
// This is wrong in multiple ways:
const d = new Date(timestamp);
d.toLocaleString('ko-KR', { timeZone: 'Asia/Seoul' });
// - Browser behavior varies
// - DST transitions handled inconsistently
// - "Asia/Seoul" availability depends on OS
Server-Side via API (Reliable)
import requests
from datetime import datetime
def convert_timezone(timestamp: str, from_tz: str, to_tz: str) -> dict:
resp = requests.get("https://api.lazy-mac.com/timezone/convert", params={
"datetime": timestamp,
"from_timezone": from_tz,
"to_timezone": to_tz
})
return resp.json()
result = convert_timezone("2026-04-11T09:00:00", "America/New_York", "Asia/Seoul")
# {
# "original": "2026-04-11T09:00:00",
# "converted": "2026-04-11T22:00:00",
# "from_tz": "America/New_York",
# "to_tz": "Asia/Seoul",
# "offset_diff": "+13:00",
# "dst_active_from": false,
# "dst_active_to": false
# }
Meeting Scheduler Pattern
def find_meeting_time(participants: list[dict]) -> list:
"""
participants = [
{"name": "Alice", "timezone": "America/New_York", "working_hours": [9, 17]},
{"name": "Bob", "timezone": "Asia/Seoul", "working_hours": [9, 18]},
]
"""
resp = requests.post("https://api.lazy-mac.com/timezone/find-overlap", json={
"participants": participants,
"duration_minutes": 60,
"date": "2026-04-15"
})
return resp.json()['available_slots']
List All Timezones
resp = requests.get("https://api.lazy-mac.com/timezone/list", params={
"region": "Asia",
"include_offset": True,
"current_time": True
})
# Returns all Asia/* timezones with current local time
Top comments (0)