Date & Intl
Working with dates and times in JavaScript — the Date object, common pitfalls, and Intl for locale-aware formatting.
What it is, in plain English: Date is JavaScript's built-in object for working with dates and times. It stores a moment as milliseconds since 1 January 1970 UTC (Unix epoch). The Intl API (Internationalisation) provides locale-aware formatting for dates, numbers, currencies, and relative times — so '3 days ago' and '$1,234.56' render correctly for any language and region without writing the logic yourself.
Working with dates and formatting them for users
Creating a Date
// The current date and time:
const now = new Date();
console.log(now); // something like: Fri Jun 27 2026 14:30:00 GMT+0530
// A specific date from an ISO string (recommended format):
const launch = new Date("2026-01-15");
const meeting = new Date("2026-06-27T14:30:00");
// From individual parts (trap: months are 0-indexed!):
const d = new Date(2026, 5, 27); // June 27, 2026 — month 5, not 6!
// This is one of JS's most famous gotchas. Always use ISO strings when possible.
Months are 0-indexed. January = 0, February = 1, ... December = 11.
This trips everyone. If you pass month numbers as arguments, subtract 1.
Using ISO string format (
"2026-06-27") avoids this entirely.
Getting parts of a date
const d = new Date("2026-06-27T14:30:00");
d.getFullYear() // 2026
d.getMonth() // 5 ← June (0-indexed — add 1 to display)
d.getDate() // 27 (day of month, 1-31)
d.getDay() // 6 (day of week: 0=Sunday, 6=Saturday)
d.getHours() // 14
d.getMinutes() // 30
d.getSeconds() // 0
// The safe, unambiguous string formats:
d.toISOString() // "2026-06-27T09:00:00.000Z" — UTC, always use for storage
d.toLocaleDateString() // "6/27/2026" — locale-dependent, only for display
d.toDateString() // "Sat Jun 27 2026" — human-readable but not locale-awareDate arithmetic — using timestamps
The safest way to do date arithmetic is with timestamps — milliseconds since the Unix epoch (1 Jan 1970 UTC). Every Date can become a timestamp and back.
// Get timestamp:
const now = Date.now(); // milliseconds since epoch (no object needed)
const ts = new Date().getTime(); // same thing via a Date object
// Calculate future/past dates:
const ONE_DAY_MS = 24 * 60 * 60 * 1000; // 86,400,000
const ONE_WEEK_MS = 7 * ONE_DAY_MS;
const today = new Date();
const tomorrow = new Date(today.getTime() + ONE_DAY_MS);
const lastWeek = new Date(today.getTime() - ONE_WEEK_MS);
console.log(tomorrow.toDateString()); // tomorrow's date
console.log(lastWeek.toDateString()); // last week
// Difference between two dates:
const start = new Date("2026-01-01");
const end = new Date("2026-06-27");
const diffMs = end.getTime() - start.getTime();
const diffDays = Math.floor(diffMs / ONE_DAY_MS);
console.log(`${diffDays} days between them`); // 177 daysIntl — let the browser format dates and numbers
Never write your own date formatter. The Intl API does it correctly
for every locale, timezone, and language automatically.
const date = new Date("2026-06-27T14:30:00");
// DateTimeFormat — pick your locale and style:
new Intl.DateTimeFormat("en-US").format(date) // "6/27/2026"
new Intl.DateTimeFormat("en-GB").format(date) // "27/06/2026"
new Intl.DateTimeFormat("en-IN").format(date) // "27/6/2026"
new Intl.DateTimeFormat("de-DE").format(date) // "27.6.2026"
new Intl.DateTimeFormat("ja-JP").format(date) // "2026/6/27"
// Control what's shown:
const fmt = new Intl.DateTimeFormat("en-IN", {
weekday: "long", // "Saturday"
year: "numeric",
month: "long", // "June"
day: "numeric",
hour: "2-digit",
minute: "2-digit",
timeZoneName: "short"
});
console.log(fmt.format(date));
// "Saturday, June 27, 2026, 02:30 PM IST"
// NumberFormat for currency:
const price = 1234.56;
new Intl.NumberFormat("en-IN", { style: "currency", currency: "INR" }).format(price)
// "₹1,234.56"
new Intl.NumberFormat("en-US", { style: "currency", currency: "USD" }).format(price)
// "$1,234.56"Relative time: "3 days ago"
const rtf = new Intl.RelativeTimeFormat("en", { numeric: "auto" });
rtf.format(-1, "day") // "yesterday"
rtf.format(-3, "day") // "3 days ago"
rtf.format(0, "day") // "today"
rtf.format(1, "day") // "tomorrow"
rtf.format(-2, "week") // "2 weeks ago"
rtf.format(1, "month") // "next month"
// Calculate which unit to use:
function timeAgo(date) {
const diffMs = date.getTime() - Date.now();
const diffSec = Math.round(diffMs / 1000);
const diffMin = Math.round(diffSec / 60);
const diffHr = Math.round(diffMin / 60);
const diffDay = Math.round(diffHr / 24);
if (Math.abs(diffSec) < 60) return rtf.format(diffSec, "second");
if (Math.abs(diffMin) < 60) return rtf.format(diffMin, "minute");
if (Math.abs(diffHr) < 24) return rtf.format(diffHr, "hour");
return rtf.format(diffDay, "day");
}
console.log(timeAgo(new Date(Date.now() - 5 * 60 * 1000))); // "5 minutes ago"
Try It Yourself
Official Sources
- MDN Web Docs — Date
- MDN Web Docs — Intl
- TC39 Temporal Proposal
- ECMAScript Internationalisation API (ECMA-402)
- MDN Web Docs — Intl.RelativeTimeFormat
The Codex links only to official documentation and the ECMAScript specification. No third-party tutorials.