HeoLab
ToolsBlogAboutContact
HeoLab

Free developer tools with AI enhancement. Built for developers who ship.

Tools

  • JSON Formatter
  • JWT Decoder
  • Base64 Encoder
  • Timestamp Converter
  • Regex Tester
  • All Tools →

Resources

  • Blog
  • What is JSON?
  • JWT Deep Dive
  • Base64 Explained

Company

  • About
  • Contact
  • Privacy Policy
  • Terms of Service

© 2026 HeoLab. All rights reserved.

Tools work in your browser. Zero data retention.

HomeBlogJavaScript's Intl API: Working with Time Zones, Dates, and Locales
Table of Contents▾
  • Why the Intl API Exists
  • Intl.DateTimeFormat — The Foundation
  • Time Zone Handling
  • IANA Time Zone Database
  • Converting Between Time Zones
  • Intl.RelativeTimeFormat — Human-Friendly Durations
  • Intl.NumberFormat — Currency and Numbers
  • Intl.ListFormat — Human-Readable Lists
  • Conclusion
tutorials#javascript#intl#timezones

JavaScript's Intl API: Working with Time Zones, Dates, and Locales

The Intl API is one of JavaScript's most powerful and least-known features. Master Intl.DateTimeFormat, Intl.RelativeTimeFormat, and timezone handling for global apps.

Trong Ngo
March 3, 2026
4 min read

Why the Intl API Exists

Formatting dates, numbers, and currencies correctly for different locales is surprisingly complex. The Vietnamese date format is ngày 3 tháng 3, 2025 — not 03/03/2025. German uses commas for decimals: 1.234,56. Arabic numbers flow right-to-left. Before Intl, developers shipped multi-megabyte i18n libraries to handle this. The Intl API does it natively, in ~5KB.

Intl.DateTimeFormat — The Foundation

// Basic formatting
new Intl.DateTimeFormat("en-US").format(new Date())
// "3/3/2025"

new Intl.DateTimeFormat("de-DE").format(new Date())
// "3.3.2025"

new Intl.DateTimeFormat("vi-VN").format(new Date())
// "3/3/2025" (uses / separator, but with Vietnamese locale context)

// Full date with time
new Intl.DateTimeFormat("en-US", {
  dateStyle: "full",
  timeStyle: "long",
  timeZone: "America/New_York"
}).format(new Date())
// "Monday, March 3, 2025 at 10:30:00 AM EST"

// Individual components
new Intl.DateTimeFormat("en-US", {
  weekday: "long",
  year: "numeric",
  month: "long",
  day: "numeric"
}).format(new Date())
// "Monday, March 3, 2025"

Time Zone Handling

IANA Time Zone Database

JavaScript uses IANA timezone identifiers (e.g., America/New_York, Asia/Ho_Chi_Minh). These are more precise than abbreviations like "EST" (which is ambiguous — Brazil also has "EST").

// Get user's local timezone
Intl.DateTimeFormat().resolvedOptions().timeZone
// "Asia/Ho_Chi_Minh" (Vietnam)
// "America/Los_Angeles" (US Pacific)

// Display the same moment in multiple timezones
const now = new Date()
const timezones = ["UTC", "America/New_York", "Europe/London", "Asia/Tokyo", "Asia/Ho_Chi_Minh"]

timezones.forEach(tz => {
  const formatted = new Intl.DateTimeFormat("en-US", {
    timeZone: tz,
    hour: "2-digit",
    minute: "2-digit",
    timeZoneName: "short"
  }).format(now)
  console.log(`${tz.padEnd(25)} ${formatted}`)
})

Converting Between Time Zones

// Get hours/minutes in a specific timezone
function getTimeInZone(date, timezone) {
  const parts = new Intl.DateTimeFormat("en-US", {
    timeZone: timezone,
    hour: "numeric",
    minute: "numeric",
    hour12: false
  }).formatToParts(date)

  const hour = parts.find(p => p.type === "hour")?.value
  const minute = parts.find(p => p.type === "minute")?.value
  return `${hour}:${minute}`
}

getTimeInZone(new Date(), "Asia/Ho_Chi_Minh")  // "17:30" (UTC+7)

Intl.RelativeTimeFormat — Human-Friendly Durations

const rtf = new Intl.RelativeTimeFormat("en", { numeric: "auto" })

rtf.format(-1, "day")     // "yesterday"
rtf.format(1, "day")      // "tomorrow"
rtf.format(-3, "hour")    // "3 hours ago"
rtf.format(2, "week")     // "in 2 weeks"

// Vietnamese
const rtfVI = new Intl.RelativeTimeFormat("vi", { numeric: "auto" })
rtfVI.format(-1, "day")   // "hôm qua"
rtfVI.format(1, "week")   // "tuần sau"

// Smart relative time utility
function timeAgo(date) {
  const rtf = new Intl.RelativeTimeFormat("en", { numeric: "auto" })
  const seconds = Math.floor((Date.now() - date.getTime()) / 1000)

  const ranges = [
    [60, "second", 1],
    [3600, "minute", 60],
    [86400, "hour", 3600],
    [604800, "day", 86400],
    [2592000, "week", 604800],
    [31536000, "month", 2592000],
    [Infinity, "year", 31536000]
  ]

  for (const [limit, unit, divisor] of ranges) {
    if (Math.abs(seconds) < limit) {
      return rtf.format(-Math.round(seconds / divisor), unit)
    }
  }
}

timeAgo(new Date(Date.now() - 90000))  // "2 minutes ago"
timeAgo(new Date(Date.now() - 86400000 * 3))  // "3 days ago"

Intl.NumberFormat — Currency and Numbers

// Currency
new Intl.NumberFormat("en-US", { style: "currency", currency: "USD" }).format(1234.5)
// "$1,234.50"

new Intl.NumberFormat("vi-VN", { style: "currency", currency: "VND" }).format(25000000)
// "25.000.000 ₫"

// Compact notation
new Intl.NumberFormat("en", { notation: "compact" }).format(1500000)
// "1.5M"

// Percentages
new Intl.NumberFormat("en", { style: "percent", minimumFractionDigits: 1 }).format(0.8534)
// "85.3%"

Intl.ListFormat — Human-Readable Lists

const lf = new Intl.ListFormat("en", { style: "long", type: "conjunction" })
lf.format(["apples", "bananas", "oranges"])
// "apples, bananas, and oranges"

const lfVI = new Intl.ListFormat("vi")
lfVI.format(["Hà Nội", "TP. Hồ Chí Minh", "Đà Nẵng"])
// "Hà Nội, TP. Hồ Chí Minh và Đà Nẵng"

HeoLab's World Clock is built entirely on Intl.DateTimeFormat — displaying the current time across 40+ cities with no external libraries.

Conclusion

The Intl API eliminates the need for heavy date/i18n libraries in most cases. DateTimeFormat handles timezone conversion and locale-appropriate formatting; RelativeTimeFormat gives you "2 hours ago" strings in any language; NumberFormat formats currencies and percentages correctly. Reach for Intl first before adding moment.js or similar dependencies.

Try These Tools

World Clock

See the current time in multiple cities simultaneously. Live updates every second with day/night indicators.

Unix Timestamp Converter

Convert Unix timestamps to human-readable dates and vice versa. Supports all major timezone formats.

Date Calculator

Add or subtract days, weeks, months, or years from any date. See the result in multiple formats.

Related Articles

Why Math.random() Is Dangerous for Security (And What to Use Instead)

4 min read

QR Codes in Web Apps: Generate, Customize, and Decode

4 min read

Web Performance Optimization: A Practical Developer's Guide

3 min read

Back to Blog

Table of Contents

  • Why the Intl API Exists
  • Intl.DateTimeFormat — The Foundation
  • Time Zone Handling
  • IANA Time Zone Database
  • Converting Between Time Zones
  • Intl.RelativeTimeFormat — Human-Friendly Durations
  • Intl.NumberFormat — Currency and Numbers
  • Intl.ListFormat — Human-Readable Lists
  • Conclusion

Related Articles

Why Math.random() Is Dangerous for Security (And What to Use Instead)

4 min read

QR Codes in Web Apps: Generate, Customize, and Decode

4 min read

Web Performance Optimization: A Practical Developer's Guide

3 min read