Here’s a detailed guide to formatting JavaScript dates as yyyy-mm-dd
, including various methods, time zone considerations, edge cases, and practical examples:
1. Manual Formatting (Local Time)
Best for: Browser local time formatting
Handles: Time zone offsets, padding single-digit days/months
function formatLocalDate(date) {
const year = date.getFullYear();
const month = String(date.getMonth() + 1).padStart(2, '0'); // Months 0-11 → 01-12
const day = String(date.getDate()).padStart(2, '0');
return `${year}-${month}-${day}`;
}
// Example 1: Current date
console.log(formatLocalDate(new Date())); // "2023-09-05"
// Example 2: Specific date (December 5, 2023)
const date1 = new Date(2023, 11, 5); // Month is 0-based (11 = December)
console.log(formatLocalDate(date1)); // "2023-12-05"
// Example 3: Single-digit day/month (January 9, 2024)
const date2 = new Date(2024, 0, 9); // 0 = January
console.log(formatLocalDate(date2)); // "2024-01-09"
2. toISOString()
Method (UTC Time)
Best for: UTC time formatting
Note: May differ from local date near midnight due to timezone offsets
function formatUTCDate(date) {
return date.toISOString().split('T')[0];
}
// Example 1: Current UTC date
console.log(formatUTCDate(new Date())); // "2023-09-05" (UTC)
// Example 2: Near midnight (Local: 2023-12-31 23:00 → UTC: 2024-01-01)
const localDate = new Date('2023-12-31T23:00:00');
console.log(formatUTCDate(localDate)); // "2024-01-01"
3. Handling Time Zone Differences
Local vs. UTC Date
// User in New York (UTC-4) on 2023-12-31 20:30 local time
const date = new Date('2023-12-31T20:30:00-04:00');
// Local formatting: "2023-12-31"
console.log(formatLocalDate(date));
// UTC formatting: "2024-01-01" (20:30-04:00 = 00:30 UTC next day)
console.log(formatUTCDate(date));
4. Edge Cases
Invalid Dates
const invalidDate = new Date('invalid-date-string');
console.log(formatLocalDate(invalidDate)); // "NaN-aN-aN"
Solution: Validate dates first:
function safeFormatDate(date) {
if (isNaN(date)) return 'Invalid Date';
return formatLocalDate(date);
}
Cross-Browser Padding (No padStart
Support)
For older browsers (IE), use:
function pad(n) { return n < 10 ? '0' + n : n; }
function formatDateLegacy(date) {
const year = date.getFullYear();
const month = pad(date.getMonth() + 1);
const day = pad(date.getDate());
return `${year}-${month}-${day}`;
}
5. Reusable Utility Function
function formatDate(date, useUTC = false) {
if (useUTC) {
return date.toISOString().split('T')[0];
} else {
const year = date.getFullYear();
const month = String(date.getMonth() + 1).padStart(2, '0');
const day = String(date.getDate()).padStart(2, '0');
return `${year}-${month}-${day}`;
}
}
// Usage:
console.log(formatDate(new Date())); // Local: "2023-09-05"
console.log(formatDate(new Date(), true)); // UTC: "2023-09-05"
6. Input Scenarios
From Timestamp
const timestamp = 1693862400000; // 2023-09-05 00:00:00 UTC
console.log(formatDate(new Date(timestamp), true)); // "2023-09-05"
From Date String
const dateStr = 'March 15, 2024 03:24:00';
console.log(formatDate(new Date(dateStr))); // "2024-03-15"
Comparison Table
Method | formatLocalDate | formatUTCDate |
---|---|---|
Time Zone | Local | UTC |
Midnight Handling | Local date | May roll over |
Browser Support | All (with polyfill) | All |
Use Case | User-facing dates | Server/API dates |
When to Use Which
- Local Dates: User interfaces, forms, local event dates.
- UTC Dates: Database storage, APIs, global applications.
This guide covers all common scenarios for formatting dates in yyyy-mm-dd
in JavaScript!