Date and Time Correctly in Javascript
Handling date and time looks simple at first—until users from different countries start seeing the wrong day, wrong hour, or wrong format. In frontend applications, most date/time bugs are not logic bugs—they are timezone and formatting bugs.
This article explains how to display date and time correctly and safely in frontend applications using JavaScript.
1. Understand the Core Problem: Timezones
JavaScript runs in the user’s browser, which means:
The browser has its own timezone
Backend APIs often send dates in UTC
If you display dates without thinking about timezone → bugs happen
Example API response
{
"createdAt": "2025-12-25T22:30:00Z"
}
Zmeans UTCA user in Norway (UTC+1) should see: Dec 26, 23:30
A user in India (UTC+5:30) should see: Dec 26, 04:00
👉 Correct display depends on user timezone
2. Golden Rule for Frontend Date Handling
Always store and transmit dates in UTC.
Convert and format dates only at display time.
Why?
UTC is neutral
No daylight-saving confusion
Easy to reason about
3. Parsing Dates Correctly in JavaScript
✅ Correct: ISO 8601 format
const date = new Date("2025-12-25T22:30:00Z");
JavaScript:
Parses it as UTC
Automatically converts to local time when displayed
❌ Dangerous: Non-ISO strings
new Date("25/12/2025"); // locale-dependent, unreliable
Different browsers interpret this differently. Avoid it.
4. Never Use toString() for UI
date.toString();
// "Thu Dec 26 2025 00:30:00 GMT+0100 (Central European Standard Time)"
Problems:
Long
Locale-specific
Not user-friendly
👉 Never display this directly in UI
5. Correct Way: Intl.DateTimeFormat
Intl.DateTimeFormat is the modern, correct way to format dates.
Basic example
const date = new Date("2025-12-25T22:30:00Z");
const formatted = new Intl.DateTimeFormat("en-US", {
dateStyle: "medium",
timeStyle: "short"
}).format(date);
console.log(formatted);
// Dec 26, 2025, 12:30 AM (for Norway)
Why this is good
Locale-aware
Handles timezones
Handles daylight saving
Browser optimized
6. Respect the User’s Locale
Automatic locale detection
const locale = navigator.language;
new Intl.DateTimeFormat(locale, {
dateStyle: "long",
timeStyle: "short"
}).format(date);
Examples:
US →
December 26, 2025Norway →
26. desember 2025Germany →
26. Dezember 2025
👉 Never hardcode date formats like DD/MM/YYYY
7. Explicit Timezone Handling (Advanced)
Sometimes you must display a date in a specific timezone, not the user’s.
Example: Always show UTC
new Intl.DateTimeFormat("en-GB", {
timeZone: "UTC",
dateStyle: "medium",
timeStyle: "short"
}).format(date);
Example: Show New York time
new Intl.DateTimeFormat("en-US", {
timeZone: "America/New_York",
dateStyle: "medium",
timeStyle: "short"
}).format(date);
This is critical for:
Financial apps
Booking systems
Logs and audits
8. Display Relative Time (User-Friendly)
Instead of:
“2025-12-25 22:30”
Use:
“5 minutes ago”
Using Intl.RelativeTimeFormat
const rtf = new Intl.RelativeTimeFormat("en", { numeric: "auto" });
rtf.format(-5, "minute");
// "5 minutes ago"
Common pattern
function getRelativeTime(date) {
const diff = date - new Date();
const minutes = Math.round(diff / 60000);
return rtf.format(minutes, "minute");
}
Great for:
Notifications
Activity feeds
Chat apps
9. Date vs Date-Time: Don’t Mix Them
Date only (birthdays, holidays)
new Intl.DateTimeFormat("en-GB", {
dateStyle: "long"
}).format(date);
Date + time (logs, messages)
new Intl.DateTimeFormat("en-GB", {
dateStyle: "medium",
timeStyle: "short"
}).format(date);
👉 Don’t show time if it’s not meaningful
10. Common Frontend Date Mistakes
❌ Formatting dates manually
`${date.getDate()}/${date.getMonth() + 1}/${date.getFullYear()}`
Breaks for:
Locale
Leading zeros
Month names
Accessibility
❌ Assuming server timezone
Frontend does not know backend timezone unless told.
❌ Ignoring daylight saving time
This causes off-by-one-hour bugs that appear twice a year.
11. When Should You Use a Date Library?
Native Intl is enough for:
Displaying dates
Formatting
Timezone conversion
Consider libraries only when you need:
Complex date math
Calendar calculations
Heavy scheduling logic
Modern choices:
date-fns (recommended)
Luxon
Avoid Moment.js (legacy)
12. Practical Checklist for Production Apps
Before shipping date/time UI, check:
✅ Backend sends UTC
✅ ISO 8601 format used
✅
Intl.DateTimeFormatused for display✅ User locale respected
✅ Timezone explicit when required
✅ Relative time for feeds
✅ No manual string formatting
Final Takeaway
Date and time are not strings.
They are global, contextual data that must respect users, locales, and timezones.
If you:
Store in UTC
Parse ISO strings
Format using
IntlDisplay thoughtfully
👉 Your frontend will be correct, accessible, and production-safe.