JavaScript 48 🧬 Date and time
const now = new Date();
console.log(now);
const specific = new Date('2024-01-15T10:30:00');
console.log(specific);
const fromParts = new Date(2024, 0, 15, 10, 30, 0);
console.log(fromParts);
const timestamp = Date.now();
console.log(timestamp);
console.log(now.getFullYear());
console.log(now.getMonth());
console.log(now.getDate());
console.log(now.getDay());
console.log(now.getHours());
console.log(now.getMinutes());
console.log(now.getSeconds());
console.log(now.getMilliseconds());
console.log(now.getTime());
now.setFullYear(2025);
now.setMonth(5);
now.setDate(20);
console.log(now.toISOString());
console.log(now.toDateString());
console.log(now.toTimeString());
console.log(now.toLocaleDateString());
console.log(now.toLocaleTimeString());
console.log(now.toLocaleString());
const d1 = new Date('2024-01-15');
const d2 = new Date('2024-06-20');
console.log(d2 - d1);
console.log(Date.parse('2024-01-15'));
console.log(Date.UTC(2024, 0, 15));
The Date object represents a single moment in time. It’s been in JavaScript since the beginning, and it carries some quirks — zero-indexed months, mutable objects, inconsistent parsing. But it’s also unavoidable, because every application eventually needs to show, compare, or manipulate dates.
Key point: A Date is stored as milliseconds since the Unix epoch — January 1, 1970, 00:00:00 UTC. Everything else (year, month, day, timezone) is derived from that single number. Understanding this makes the API much less mysterious.
a – What is a Date
A Date object represents a point in time. Internally it’s a single number: milliseconds since the epoch.
Creating a Date:
| Form | Example | Meaning |
|---|---|---|
| Current | new Date() | Right now |
| From string | new Date('2024-01-15') | Parsed |
| From parts | new Date(2024, 0, 15) | Year, month, day |
| From timestamp | new Date(1705314600000) | Milliseconds since epoch |
| From another Date | new Date(otherDate) | Copy |
Current time:
const now = new Date();
console.log(now);
// [ 2024-01-15T10:30:00.000Z ]
This is the current moment — with milliseconds precision.
From a string:
const d1 = new Date('2024-01-15');
console.log(d1);
// [ 2024-01-15T00:00:00.000Z ]
const d2 = new Date('2024-01-15T10:30:00');
console.log(d2);
// [ 2024-01-15T10:30:00.000Z ]
const d3 = new Date('January 15, 2024');
console.log(d3);
// [ 2024-01-15T00:00:00.000Z ]
⚠️ Warning: Date string parsing is implementation-dependent.
'2024-01-15'is treated as UTC in modern engines, but'2024/01/15'or'January 15, 2024'may be local time. For reliable parsing, use ISO 8601 format (YYYY-MM-DDTHH:mm:ss) orDate.parse()with explicit timezone. For critical code, avoid parsing strings — build from parts.
From parts:
const d = new Date(2024, 0, 15, 10, 30, 0, 0);
console.log(d);
// [ 2024-01-15T10:30:00.000Z ] (in UTC timezone)
| Argument | Meaning | Range |
|---|---|---|
| Year | Full year | — |
| Month | 0-indexed (0 = Jan) | 0–11 |
| Day | Day of month | 1–31 |
| Hours | 24-hour | 0–23 |
| Minutes | — | 0–59 |
| Seconds | — | 0–59 |
| Milliseconds | — | 0–999 |
Note: Month is 0-indexed! January is
0, December is11. This is one of the most common sources of bugs.
From a timestamp:
const epoch = new Date(0);
console.log(epoch);
// [ 1970-01-01T00:00:00.000Z ]
const ts = new Date(1705314600000);
console.log(ts);
// [ 2024-01-15T10:30:00.000Z ]
Date.now() — current timestamp in milliseconds:
console.log(Date.now());
// [ 1705314600000 ]
Faster than new Date().getTime() — no object allocation.
The epoch concept:
┌──────────────────────────────────────────────┐
│ │
│ 1970-01-01T00:00:00 UTC │
│ │ │
│ │ milliseconds │
│ ▼ │
│ ┌────────────────────────┐ │
│ │ 0 │ ← epoch │
│ │ 1000 │ ← 1 second later│
│ │ 1705314600000 │ ← 2024-01-15 │
│ │ -1000 │ ← 1 second before│
│ └────────────────────────┘ │
│ │
│ A Date is just a number │
│ │
└──────────────────────────────────────────────┘
Dates are mutable:
const d = new Date('2024-01-15');
d.setFullYear(2025);
console.log(d);
// [ 2025-01-15T00:00:00.000Z ]
Unlike strings and numbers, Date objects change in place. This is a common source of bugs.
Invalid dates:
const bad = new Date('not a date');
console.log(bad);
// [ Invalid Date ]
console.log(isNaN(bad));
// [ true ]
console.log(bad.getTime());
// [ NaN ]
An Invalid Date is a Date object whose internal number is NaN. Always check with isNaN(date.getTime()).
Timezones:
The Date object has two “views” — UTC and local. Getter methods come in pairs:
| Local | UTC |
|---|---|
getFullYear() | getUTCFullYear() |
getMonth() | getUTCMonth() |
getDate() | getUTCDate() |
getHours() | getUTCHours() |
getDay() | getUTCDay() |
Local methods use your system’s timezone. UTC methods use UTC. The stored timestamp is the same.
const d = new Date('2024-01-15T10:30:00Z');
console.log(d.getHours()); // depends on your timezone
console.log(d.getUTCHours()); // 10
Comparing dates:
const a = new Date('2024-01-15');
const b = new Date('2024-06-20');
console.log(a < b);
// [ true ]
console.log(a > b);
// [ false ]
console.log(a - b);
// [ -13536000000 ] ← milliseconds difference
Comparison operators work because Dates coerce to numbers. But === compares references:
const a = new Date('2024-01-15');
const b = new Date('2024-01-15');
console.log(a === b);
// [ false ] ← different objects
console.log(a.getTime() === b.getTime());
// [ true ] ← same instant
b – Date methods and formatting
The Date API has dozens of methods. This section covers the ones you’ll actually use.
Getters — reading components:
| Method | Returns |
|---|---|
getFullYear() | 4-digit year |
getMonth() | 0–11 |
getDate() | 1–31 |
getDay() | 0–6 (Sunday = 0) |
getHours() | 0–23 |
getMinutes() | 0–59 |
getSeconds() | 0–59 |
getMilliseconds() | 0–999 |
getTime() | Milliseconds since epoch |
getTimezoneOffset() | Minutes offset from UTC |
Reading components:
const d = new Date('2024-01-15T10:30:45.123');
console.log(d.getFullYear());
// [ 2024 ]
console.log(d.getMonth());
// [ 0 ] ← January
console.log(d.getDate());
// [ 15 ]
console.log(d.getDay());
// [ 1 ] ← Monday (Sunday = 0)
console.log(d.getHours());
// [ 10 ]
console.log(d.getMinutes());
// [ 30 ]
console.log(d.getSeconds());
// [ 45 ]
console.log(d.getMilliseconds());
// [ 123 ]
console.log(d.getTime());
// [ 1705314645123 ]
Day of week names:
const days = ['Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat'];
const d = new Date();
console.log(days[d.getDay()]);
// [ Mon ]
Setters — changing components:
| Method | Meaning |
|---|---|
setFullYear(y) | Set year |
setMonth(m) | Set month (0–11) |
setDate(d) | Set day |
setHours(h) | Set hours |
setMinutes(m) | Set minutes |
setSeconds(s) | Set seconds |
setMilliseconds(ms) | Set milliseconds |
setTime(ts) | Set from timestamp |
Setting components:
const d = new Date('2024-01-15');
d.setFullYear(2025);
d.setMonth(5);
d.setDate(20);
console.log(d.toISOString());
// [ 2025-06-20T00:00:00.000Z ]
setDate and month rollover:
const d = new Date('2024-01-31');
d.setMonth(1); // February
console.log(d.toISOString());
// [ 2024-03-02T00:00:00.000Z ] ← rolled over
February doesn’t have a 31st, so the Date rolls forward. This is intentional but surprising.
Formatting methods:
| Method | Output |
|---|---|
toString() | Full string with timezone |
toDateString() | Date part only |
toTimeString() | Time part only |
toISOString() | ISO 8601 UTC |
toUTCString() | Human-readable UTC |
toLocaleString() | Localized date + time |
toLocaleDateString() | Localized date |
toLocaleTimeString() | Localized time |
toJSON() | Same as toISOString |
Examples:
const d = new Date('2024-01-15T10:30:00');
console.log(d.toString());
// [ Mon Jan 15 2024 10:30:00 GMT+0000 (Coordinated Universal Time) ]
console.log(d.toDateString());
// [ Mon Jan 15 2024 ]
console.log(d.toTimeString());
// [ 10:30:00 GMT+0000 (Coordinated Universal Time) ]
console.log(d.toISOString());
// [ 2024-01-15T10:30:00.000Z ]
console.log(d.toUTCString());
// [ Mon, 15 Jan 2024 10:30:00 GMT ]
console.log(d.toLocaleString());
// [ 1/15/2024, 10:30:00 AM ] (US locale)
console.log(d.toLocaleDateString());
// [ 1/15/2024 ]
console.log(d.toLocaleTimeString());
// [ 10:30:00 AM ]
toLocaleString with options:
const d = new Date('2024-01-15T10:30:00');
console.log(d.toLocaleDateString('en-US', {
weekday: 'long',
year: 'numeric',
month: 'long',
day: 'numeric'
}));
// [ Monday, January 15, 2024 ]
console.log(d.toLocaleTimeString('en-US', {
hour: '2-digit',
minute: '2-digit',
second: '2-digit',
hour12: false
}));
// [ 10:30:00 ]
Locale options:
| Option | Values |
|---|---|
weekday | 'long', 'short', 'narrow' |
year | 'numeric', '2-digit' |
month | 'numeric', '2-digit', 'long', 'short', 'narrow' |
day | 'numeric', '2-digit' |
hour | 'numeric', '2-digit' |
minute | 'numeric', '2-digit' |
second | 'numeric', '2-digit' |
hour12 | true / false |
timeZone | 'UTC', 'America/New_York', etc. |
timeZoneName | 'short', 'long' |
Intl.DateTimeFormat — reusable formatter:
const fmt = new Intl.DateTimeFormat('en-US', {
dateStyle: 'full',
timeStyle: 'short'
});
console.log(fmt.format(new Date()));
// [ Monday, January 15, 2024 at 10:30 AM ]
Creating a formatter once and reusing it is faster than calling toLocaleString repeatedly.
Intl.RelativeTimeFormat — “2 days ago”:
const rtf = new Intl.RelativeTimeFormat('en', { numeric: 'auto' });
console.log(rtf.format(-1, 'day'));
// [ yesterday ]
console.log(rtf.format(2, 'hour'));
// [ in 2 hours ]
console.log(rtf.format(-3, 'month'));
// [ 3 months ago ]
Date arithmetic — no built-in operators:
JavaScript doesn’t have date arithmetic built in. Convert to milliseconds:
const d = new Date('2024-01-15');
// Add 7 days
const nextWeek = new Date(d);
nextWeek.setDate(d.getDate() + 7);
console.log(nextWeek.toISOString());
// [ 2024-01-22T00:00:00.000Z ]
// Add 1 month
const nextMonth = new Date(d);
nextMonth.setMonth(d.getMonth() + 1);
console.log(nextMonth.toISOString());
// [ 2024-02-15T00:00:00.000Z ]
// Add 1 year
const nextYear = new Date(d);
nextYear.setFullYear(d.getFullYear() + 1);
console.log(nextYear.toISOString());
// [ 2025-01-15T00:00:00.000Z ]
Using getTime for arithmetic:
const start = new Date('2024-01-15');
const end = new Date('2024-01-20');
const diffMs = end - start;
const diffDays = diffMs / (1000 * 60 * 60 * 24);
console.log(diffDays);
// [ 5 ]
| Unit | Milliseconds |
|---|---|
| Second | 1000 |
| Minute | 1000 * 60 |
| Hour | 1000 * 60 * 60 |
| Day | 1000 * 60 * 60 * 24 |
| Week | 1000 * 60 * 60 * 24 * 7 |
Common date operations:
// Start of today
const today = new Date();
today.setHours(0, 0, 0, 0);
// End of today
const endOfDay = new Date();
endOfDay.setHours(23, 59, 59, 999);
// Beginning of month
const firstOfMonth = new Date();
firstOfMonth.setDate(1);
firstOfMonth.setHours(0, 0, 0, 0);
// Days in month
const daysInMonth = new Date(2024, 2, 0).getDate(); // Feb 2024
console.log(daysInMonth);
// [ 29 ]
Leap year check:
function isLeapYear(year) {
return new Date(year, 1, 29).getDate() === 29;
}
console.log(isLeapYear(2024));
// [ true ]
console.log(isLeapYear(2023));
// [ false ]
Date.parse and Date.UTC:
console.log(Date.parse('2024-01-15T10:30:00Z'));
// [ 1705314600000 ]
console.log(Date.UTC(2024, 0, 15, 10, 30, 0));
// [ 1705314600000 ]
Date.UTC returns a timestamp for the given UTC parts — useful for creating UTC dates:
const d = new Date(Date.UTC(2024, 0, 15));
console.log(d.toISOString());
// [ 2024-01-15T00:00:00.000Z ]
c – Common date patterns
These are the patterns you’ll use in real code — getting, formatting, comparing, and manipulating dates.
Pattern 1 — Get today’s date as YYYY-MM-DD:
function today() {
const d = new Date();
return d.toISOString().slice(0, 10);
}
console.log(today());
// [ '2024-01-15' ]
Pattern 2 — Format as YYYY-MM-DD HH:mm:ss:
function formatDate(d) {
const pad = n => String(n).padStart(2, '0');
return `${d.getFullYear()}-${pad(d.getMonth() + 1)}-${pad(d.getDate())} ` +
`${pad(d.getHours())}:${pad(d.getMinutes())}:${pad(d.getSeconds())}`;
}
console.log(formatDate(new Date()));
// [ '2024-01-15 10:30:00' ]
Pattern 3 — Add days:
function addDays(date, days) {
const result = new Date(date);
result.setDate(result.getDate() + days);
return result;
}
console.log(addDays(new Date('2024-01-15'), 10).toISOString().slice(0, 10));
// [ '2024-01-25' ]
Pattern 4 — Difference in days:
function daysBetween(a, b) {
const msPerDay = 1000 * 60 * 60 * 24;
const utcA = Date.UTC(a.getFullYear(), a.getMonth(), a.getDate());
const utcB = Date.UTC(b.getFullYear(), b.getMonth(), b.getDate());
return Math.floor((utcB - utcA) / msPerDay);
}
console.log(daysBetween(new Date('2024-01-15'), new Date('2024-01-20')));
// [ 5 ]
Using UTC avoids daylight saving time issues.
Pattern 5 — Check if same day:
function isSameDay(a, b) {
return a.getFullYear() === b.getFullYear() &&
a.getMonth() === b.getMonth() &&
a.getDate() === b.getDate();
}
console.log(isSameDay(new Date('2024-01-15T10:00'), new Date('2024-01-15T22:00')));
// [ true ]
Pattern 6 — Check if date is today:
function isToday(d) {
const today = new Date();
return isSameDay(d, today);
}
Pattern 7 — Time ago / relative time:
function timeAgo(date) {
const seconds = Math.floor((Date.now() - date.getTime()) / 1000);
if (seconds < 60) return 'just now';
if (seconds < 3600) return `${Math.floor(seconds / 60)} minutes ago`;
if (seconds < 86400) return `${Math.floor(seconds / 3600)} hours ago`;
return `${Math.floor(seconds / 86400)} days ago`;
}
console.log(timeAgo(new Date(Date.now() - 300000)));
// [ '5 minutes ago' ]
Pattern 8 — Intl.RelativeTimeFormat:
function relative(date) {
const rtf = new Intl.RelativeTimeFormat('en', { numeric: 'auto' });
const diffMs = date - Date.now();
const diffSec = Math.round(diffMs / 1000);
const diffMin = Math.round(diffSec / 60);
const diffHour = Math.round(diffMin / 60);
const diffDay = Math.round(diffHour / 24);
if (Math.abs(diffSec) < 60) return rtf.format(diffSec, 'second');
if (Math.abs(diffMin) < 60) return rtf.format(diffMin, 'minute');
if (Math.abs(diffHour) < 24) return rtf.format(diffHour, 'hour');
return rtf.format(diffDay, 'day');
}
Pattern 9 — Age from birthdate:
function age(birthdate) {
const today = new Date();
let age = today.getFullYear() - birthdate.getFullYear();
const m = today.getMonth() - birthdate.getMonth();
if (m < 0 || (m === 0 && today.getDate() < birthdate.getDate())) {
age--;
}
return age;
}
Pattern 10 — ISO week number:
function isoWeek(d) {
const date = new Date(Date.UTC(d.getFullYear(), d.getMonth(), d.getDate()));
const dayNum = date.getUTCDay() || 7;
date.setUTCDate(date.getUTCDate() + 4 - dayNum);
const yearStart = new Date(Date.UTC(date.getUTCFullYear(), 0, 1));
return Math.ceil(((date - yearStart) / 86400000 + 1) / 7);
}
Pattern 11 — Format with timezone:
const d = new Date();
console.log(d.toLocaleString('en-US', { timeZone: 'America/New_York' }));
// [ 1/15/2024, 5:30:00 AM ]
console.log(d.toLocaleString('en-US', { timeZone: 'Asia/Tokyo' }));
// [ 1/15/2024, 7:30:00 PM ]
Pattern 12 — Parse date safely:
function parseDate(str) {
const d = new Date(str);
if (isNaN(d.getTime())) {
throw new Error(`Invalid date: ${str}`);
}
return d;
}
Always check for Invalid Date after parsing.
A complete date utility module:
const DateUtil = {
today() {
const d = new Date();
d.setHours(0, 0, 0, 0);
return d;
},
addDays(date, n) {
const d = new Date(date);
d.setDate(d.getDate() + n);
return d;
},
daysBetween(a, b) {
const ms = 1000 * 60 * 60 * 24;
const utcA = Date.UTC(a.getFullYear(), a.getMonth(), a.getDate());
const utcB = Date.UTC(b.getFullYear(), b.getMonth(), b.getDate());
return Math.floor((utcB - utcA) / ms);
},
format(d, pattern = 'YYYY-MM-DD') {
const pad = n => String(n).padStart(2, '0');
return pattern
.replace('YYYY', d.getFullYear())
.replace('MM', pad(d.getMonth() + 1))
.replace('DD', pad(d.getDate()))
.replace('HH', pad(d.getHours()))
.replace('mm', pad(d.getMinutes()))
.replace('ss', pad(d.getSeconds()));
},
isSameDay(a, b) {
return a.getFullYear() === b.getFullYear() &&
a.getMonth() === b.getMonth() &&
a.getDate() === b.getDate();
},
startOfDay(d) {
const r = new Date(d);
r.setHours(0, 0, 0, 0);
return r;
},
endOfDay(d) {
const r = new Date(d);
r.setHours(23, 59, 59, 999);
return r;
}
};
Date libraries — when native Date isn’t enough:
| Library | Why use it |
|---|---|
date-fns | Functional, tree-shakeable, immutable |
Day.js | Tiny (2KB), Moment-compatible API |
Luxon | Modern, immutable, timezone-aware |
Temporal | New built-in proposal (stage 3) |
The Temporal API is a much better date library being added to JavaScript itself. It fixes all the Date quirks — immutable objects, 1-indexed months, proper timezone handling, duration types. Until it’s widely available, libraries fill the gap.
Complete Example Session
// ============================================
// PART 1: CREATE A DATE
// ============================================
const now = new Date();
console.log(typeof now);
// [ 'object' ]
// ============================================
// PART 2: FROM STRING
// ============================================
const specific = new Date('2024-01-15T10:30:00');
console.log(specific.toISOString());
// [ '2024-01-15T10:30:00.000Z' ]
// ============================================
// PART 3: FROM PARTS
// ============================================
const fromParts = new Date(2024, 0, 15, 10, 30, 0);
console.log(fromParts.getFullYear());
// [ 2024 ]
console.log(fromParts.getMonth());
// [ 0 ]
// ============================================
// PART 4: TIMESTAMP
// ============================================
console.log(Date.now() > 0);
// [ true ]
// ============================================
// PART 5: GETTERS
// ============================================
const d = new Date('2024-01-15T10:30:45.123Z');
console.log(d.getUTCFullYear());
// [ 2024 ]
console.log(d.getUTCMonth());
// [ 0 ]
console.log(d.getUTCDate());
// [ 15 ]
console.log(d.getUTCDay());
// [ 1 ]
console.log(d.getUTCHours());
// [ 10 ]
console.log(d.getUTCMinutes());
// [ 30 ]
console.log(d.getUTCSeconds());
// [ 45 ]
console.log(d.getUTCMilliseconds());
// [ 123 ]
// ============================================
// PART 6: SETTERS
// ============================================
const d2 = new Date('2024-01-15');
d2.setFullYear(2025);
d2.setMonth(5);
d2.setDate(20);
console.log(d2.toISOString());
// [ '2025-06-20T00:00:00.000Z' ]
// ============================================
// PART 7: FORMATTING
// ============================================
const d3 = new Date('2024-01-15T10:30:00Z');
console.log(d3.toISOString());
// [ '2024-01-15T10:30:00.000Z' ]
console.log(d3.toDateString());
// [ 'Mon Jan 15 2024' ]
console.log(d3.toTimeString().slice(0, 8));
// [ '10:30:00' ]
// ============================================
// PART 8: LOCALE FORMATTING
// ============================================
console.log(d3.toLocaleDateString('en-US'));
// [ '1/15/2024' ]
console.log(d3.toLocaleDateString('en-GB'));
// [ '15/01/2024' ]
console.log(d3.toLocaleDateString('en-US', { weekday: 'long' }));
// [ 'Monday' ]
// ============================================
// PART 9: COMPARING
// ============================================
const a = new Date('2024-01-15');
const b = new Date('2024-06-20');
console.log(a < b);
// [ true ]
console.log(b - a);
// [ 13536000000 ]
// ============================================
// PART 10: DIFFERENCE IN DAYS
// ============================================
const diffMs = b - a;
const diffDays = diffMs / (1000 * 60 * 60 * 24);
console.log(diffDays);
// [ 156.66666666666666 ]
// ============================================
// PART 11: ADD DAYS
// ============================================
function addDays(date, n) {
const r = new Date(date);
r.setDate(r.getDate() + n);
return r;
}
console.log(addDays(a, 7).toISOString().slice(0, 10));
// [ '2024-01-22' ]
// ============================================
// PART 12: INVALID DATE
// ============================================
const bad = new Date('not a date');
console.log(isNaN(bad));
// [ true ]
console.log(bad.toString());
// [ 'Invalid Date' ]
// ============================================
// PART 13: DATE.PARSE
// ============================================
console.log(Date.parse('2024-01-15T00:00:00Z'));
// [ 1705276800000 ]
// ============================================
// PART 14: DATE.UTC
// ============================================
console.log(Date.UTC(2024, 0, 15));
// [ 1705276800000 ]
// ============================================
// PART 15: ISO WEEK
// ============================================
function isoWeek(d) {
const date = new Date(Date.UTC(d.getFullYear(), d.getMonth(), d.getDate()));
const dayNum = date.getUTCDay() || 7;
date.setUTCDate(date.getUTCDate() + 4 - dayNum);
const yearStart = new Date(Date.UTC(date.getUTCFullYear(), 0, 1));
return Math.ceil(((date - yearStart) / 86400000 + 1) / 7);
}
console.log(isoWeek(new Date('2024-01-15')));
// [ 3 ]
// ============================================
// PART 16: DAYS IN MONTH
// ============================================
console.log(new Date(2024, 2, 0).getDate());
// [ 29 ]
// ============================================
// PART 17: LEAP YEAR
// ============================================
function isLeapYear(year) {
return new Date(year, 1, 29).getDate() === 29;
}
console.log(isLeapYear(2024));
// [ true ]
console.log(isLeapYear(2023));
// [ false ]
// ============================================
// PART 18: RELATIVE TIME
// ============================================
const rtf = new Intl.RelativeTimeFormat('en', { numeric: 'auto' });
console.log(rtf.format(-1, 'day'));
// [ 'yesterday' ]
console.log(rtf.format(2, 'hour'));
// [ 'in 2 hours' ]
// ============================================
// PART 19: TIMEZONE
// ============================================
const d4 = new Date('2024-01-15T10:30:00Z');
console.log(d4.toLocaleString('en-US', { timeZone: 'America/New_York' }));
// [ '1/15/2024, 5:30:00 AM' ]
// ============================================
// PART 20: FULL SCRIPT
// ============================================
const now48 = new Date();
console.log(now48);
const specific48 = new Date('2024-01-15T10:30:00');
console.log(specific48);
const fromParts48 = new Date(2024, 0, 15, 10, 30, 0);
console.log(fromParts48);
const timestamp48 = Date.now();
console.log(timestamp48);
console.log(now48.getFullYear());
console.log(now48.getMonth());
console.log(now48.getDate());
console.log(now48.getDay());
console.log(now48.getHours());
console.log(now48.getMinutes());
console.log(now48.getSeconds());
console.log(now48.getMilliseconds());
console.log(now48.getTime());
now48.setFullYear(2025);
now48.setMonth(5);
now48.setDate(20);
console.log(now48.toISOString());
console.log(now48.toDateString());
console.log(now48.toTimeString());
console.log(now48.toLocaleDateString());
console.log(now48.toLocaleTimeString());
console.log(now48.toLocaleString());
const d1_48 = new Date('2024-01-15');
const d2_48 = new Date('2024-06-20');
console.log(d2_48 - d1_48);
console.log(Date.parse('2024-01-15'));
console.log(Date.UTC(2024, 0, 15));
Quick Reference
Creating Dates
| Form | Example |
|---|---|
| Now | new Date() |
| String | new Date('2024-01-15') |
| ISO | new Date('2024-01-15T10:30:00Z') |
| Parts | new Date(2024, 0, 15, 10, 30) |
| Timestamp | new Date(1705314600000) |
| Copy | new Date(other) |
| Timestamp now | Date.now() |
| Parse | Date.parse(str) |
| UTC parts | Date.UTC(2024, 0, 15) |
Date Parts
| Arg | Meaning | Range |
|---|---|---|
| Year | Full year | — |
| Month | 0-indexed | 0–11 |
| Day | Day | 1–31 |
| Hours | 24h | 0–23 |
| Minutes | — | 0–59 |
| Seconds | — | 0–59 |
| ms | — | 0–999 |
Getters
| Method | Returns |
|---|---|
getFullYear() | Year |
getMonth() | 0–11 |
getDate() | 1–31 |
getDay() | 0–6 (Sun=0) |
getHours() | 0–23 |
getMinutes() | 0–59 |
getSeconds() | 0–59 |
getMilliseconds() | 0–999 |
getTime() | Timestamp |
getTimezoneOffset() | Minutes from UTC |
| UTC variants | Prefixed getUTC... |
Setters
| Method | Meaning |
|---|---|
setFullYear(y) | Set year |
setMonth(m) | Set month |
setDate(d) | Set day |
setHours(h) | Set hours |
setMinutes(m) | Set minutes |
setSeconds(s) | Set seconds |
setMilliseconds(ms) | Set ms |
setTime(ts) | From timestamp |
Formatting
| Method | Output |
|---|---|
toISOString() | 2024-01-15T10:30:00.000Z |
toString() | Full local string |
toDateString() | Date part only |
toTimeString() | Time part only |
toUTCString() | RFC 1123 UTC |
toLocaleString() | Localized |
toLocaleDateString() | Localized date |
toLocaleTimeString() | Localized time |
toJSON() | Same as ISO |
Locale Options
| Option | Values |
|---|---|
weekday | long, short, narrow |
year | numeric, 2-digit |
month | numeric, 2-digit, long, short |
day | numeric, 2-digit |
hour | numeric, 2-digit |
minute | numeric, 2-digit |
second | numeric, 2-digit |
hour12 | true, false |
timeZone | 'UTC', 'America/New_York', etc. |
Millisecond Units
| Unit | ms |
|---|---|
| Second | 1000 |
| Minute | 60000 |
| Hour | 3600000 |
| Day | 86400000 |
| Week | 604800000 |
Common Operations
| Task | Code |
|---|---|
| Today (midnight) | d.setHours(0,0,0,0) |
| End of day | d.setHours(23,59,59,999) |
| Add days | d.setDate(d.getDate() + n) |
| Add months | d.setMonth(d.getMonth() + n) |
| Add years | d.setFullYear(d.getFullYear() + n) |
| Difference | b - a (ms) |
| Days between | (b - a) / 86400000 |
| Same day | Compare Y/M/D |
| Format ISO date | d.toISOString().slice(0, 10) |
| Check validity | !isNaN(d.getTime()) |
Libraries
| Library | Notes |
|---|---|
date-fns | Functional, tree-shakeable |
Day.js | Tiny, Moment-compatible |
Luxon | Modern, immutable |
Temporal | Built-in (stage 3) |
Best Practices
✅ Do This:
// Use ISO 8601 strings for parsing
new Date('2024-01-15T10:30:00Z'); // ✅
// Use Date.now() for timestamps
const ts = Date.now(); // ✅
// Copy dates before modifying
const next = new Date(d);
next.setDate(next.getDate() + 1); // ✅
// Use UTC for date-only arithmetic
Date.UTC(y, m, d); // ✅
// Check for Invalid Date
if (isNaN(d.getTime())) { ... } // ✅
// Use toLocaleString for display
d.toLocaleDateString('en-US', { ... }); // ✅
// Use Intl.DateTimeFormat for reusable formatting
const fmt = new Intl.DateTimeFormat('en-US'); // ✅
// Remember month is 0-indexed
new Date(2024, 0, 15); // ✅ January
❌ Don’t Do This:
// Don't trust string parsing
new Date('01/15/2024'); // ⚠️ locale-dependent
// Don't use getYear()
d.getYear(); // ❌ deprecated (use getFullYear)
// Don't forget month is 0-indexed
new Date(2024, 1, 15); // ⚠️ February, not January
// Don't mutate dates unexpectedly
function addDay(d) {
d.setDate(d.getDate() + 1);
return d; // ❌ mutates input
}
// Don't compare with ===
d1 === d2; // ❌ reference comparison
d1.getTime() === d2.getTime(); // ✅
// Don't compute days without UTC
(b - a) / 86400000; // ⚠️ DST issues
Common Pitfalls
| Pitfall | Problem | Solution |
|---|---|---|
| Month is 0-indexed | Off-by-one | Jan is 0 |
getYear() deprecated | Wrong value | getFullYear() |
| String parsing unreliable | Different results | ISO 8601 |
| Mutating dates | Side effects | Copy first |
=== on dates | Reference compare | getTime() |
| DST breaks diffs | Off-by-one days | Use UTC |
setMonth rolls over | Feb 31 → Mar 2 | Known behavior |
| Timezone confusion | Off hours | Use getUTC/setUTC |
Date in JSON | ISO string only | Custom serialize |
Real-World Examples
1. Current Date
const now = new Date();
console.log(now.toISOString());
// [ '2024-01-15T10:30:00.000Z' ]
2. From String
const d = new Date('2024-01-15T10:30:00Z');
console.log(d.toISOString());
// [ '2024-01-15T10:30:00.000Z' ]
3. From Parts
const d = new Date(2024, 0, 15, 10, 30, 0);
console.log(d.getFullYear());
// [ 2024 ]
4. Timestamp
console.log(Date.now());
// [ 1705314600000 ]
5. Get Components
const d = new Date('2024-01-15T10:30:45Z');
console.log(d.getUTCFullYear()); // 2024
console.log(d.getUTCMonth()); // 0
console.log(d.getUTCDate()); // 15
console.log(d.getUTCHours()); // 10
console.log(d.getUTCMinutes()); // 30
6. Set Components
const d = new Date('2024-01-15');
d.setFullYear(2025);
d.setMonth(5);
d.setDate(20);
console.log(d.toISOString());
// [ '2025-06-20T00:00:00.000Z' ]
7. Format ISO
const d = new Date('2024-01-15T10:30:00Z');
console.log(d.toISOString());
// [ '2024-01-15T10:30:00.000Z' ]
8. Locale Date
const d = new Date('2024-01-15');
console.log(d.toLocaleDateString('en-US'));
// [ '1/15/2024' ]
console.log(d.toLocaleDateString('en-GB'));
// [ '15/01/2024' ]
9. Full Weekday
const d = new Date('2024-01-15');
console.log(d.toLocaleDateString('en-US', { weekday: 'long' }));
// [ 'Monday' ]
10. Compare Dates
const a = new Date('2024-01-15');
const b = new Date('2024-06-20');
console.log(a < b);
// [ true ]
11. Difference in Days
const a = new Date('2024-01-15');
const b = new Date('2024-01-20');
console.log((b - a) / 86400000);
// [ 5 ]
12. Add Days
function addDays(d, n) {
const r = new Date(d);
r.setDate(r.getDate() + n);
return r;
}
console.log(addDays(new Date('2024-01-15'), 10).toISOString().slice(0, 10));
// [ '2024-01-25' ]
13. Same Day Check
function isSameDay(a, b) {
return a.getFullYear() === b.getFullYear() &&
a.getMonth() === b.getMonth() &&
a.getDate() === b.getDate();
}
14. Start of Day
function startOfDay(d) {
const r = new Date(d);
r.setHours(0, 0, 0, 0);
return r;
}
15. Days in Month
console.log(new Date(2024, 2, 0).getDate());
// [ 29 ]
16. Leap Year
function isLeapYear(year) {
return new Date(year, 1, 29).getDate() === 29;
}
console.log(isLeapYear(2024));
// [ true ]
17. Relative Time
const rtf = new Intl.RelativeTimeFormat('en', { numeric: 'auto' });
console.log(rtf.format(-2, 'day'));
// [ '2 days ago' ]
18. Timezone Formatting
const d = new Date();
console.log(d.toLocaleString('en-US', { timeZone: 'Asia/Tokyo' }));
19. Validate
function isValidDate(d) {
return d instanceof Date && !isNaN(d.getTime());
}
20. Full Script
const now48 = new Date();
console.log(now48);
const specific48 = new Date('2024-01-15T10:30:00');
console.log(specific48);
const fromParts48 = new Date(2024, 0, 15, 10, 30, 0);
console.log(fromParts48);
const timestamp48 = Date.now();
console.log(timestamp48);
console.log(now48.getFullYear());
console.log(now48.getMonth());
console.log(now48.getDate());
console.log(now48.getDay());
console.log(now48.getHours());
console.log(now48.getMinutes());
console.log(now48.getSeconds());
console.log(now48.getMilliseconds());
console.log(now48.getTime());
now48.setFullYear(2025);
now48.setMonth(5);
now48.setDate(20);
console.log(now48.toISOString());
console.log(now48.toDateString());
console.log(now48.toTimeString());
console.log(now48.toLocaleDateString());
console.log(now48.toLocaleTimeString());
console.log(now48.toLocaleString());
const d1_48 = new Date('2024-01-15');
const d2_48 = new Date('2024-06-20');
console.log(d2_48 - d1_48);
console.log(Date.parse('2024-01-15'));
console.log(Date.UTC(2024, 0, 15));
Visual: Date Internal Representation
┌──────────────────────────────────────────────┐
│ new Date('2024-01-15T10:30:00Z') │
│ │
│ Stored internally: │
│ ┌─────────────────────────────────────┐ │
│ │ 1705314600000 │ │
│ │ (milliseconds since 1970-01-01 UTC) │ │
│ └─────────────────────────────────────┘ │
│ │
│ Same instant, different views: │
│ │
│ Local: depends on your timezone │
│ UTC: 2024-01-15T10:30:00.000Z │
│ ISO: "2024-01-15T10:30:00.000Z" │
│ Epoch: 1705314600000 │
│ │
└──────────────────────────────────────────────┘
Visual: Month is 0-Indexed
┌──────────────────────────────────────────────┐
│ Month index │
│ │
│ new Date(2024, 0, 15) → January 15 │
│ new Date(2024, 1, 15) → February 15 │
│ new Date(2024, 2, 15) → March 15 │
│ new Date(2024, 11, 15) → December 15 │
│ │
│ ⚠️ Off-by-one incoming! │
│ │
└──────────────────────────────────────────────┘
Visual: UTC vs Local
┌──────────────────────────────────────────────┐
│ Server timestamp: 1705314600000 │
│ (= 2024-01-15T10:30:00Z) │
│ │
│ Displayed in different zones: │
│ │
│ UTC: 10:30 │
│ America/New_York: 05:30 │
│ Europe/London: 10:30 │
│ Asia/Tokyo: 19:30 │
│ │
│ Same instant, different display │
│ │
└──────────────────────────────────────────────┘
Summary
| Concept | Syntax | Example |
|---|---|---|
| Now | new Date() | Current moment |
| From string | new Date('2024-01-15') | Parse ISO |
| From parts | new Date(2024, 0, 15) | Month 0-indexed |
| From timestamp | new Date(ms) | Since epoch |
| Timestamp | Date.now() | Milliseconds |
| Parse | Date.parse(str) | → ms |
| UTC parts | Date.UTC(...) | → ms |
| Get year | getFullYear() | 2024 |
| Get month | getMonth() | 0–11 |
| Get date | getDate() | 1–31 |
| Get day | getDay() | 0–6 |
| Set year | setFullYear(y) | Mutates |
| Set month | setMonth(m) | 0-indexed |
| Set date | setDate(d) | Day |
| ISO format | toISOString() | 2024-01-15T10:30:00.000Z |
| Local format | toLocaleString() | Localized |
| Custom locale | toLocaleString(locale, opts) | Full control |
| Compare | a < b | Works |
| Difference | b - a | Milliseconds |
| Days between | (b - a) / 86400000 | Number |
| Add days | d.setDate(d.getDate() + n) | Mutates |
| Check valid | !isNaN(d.getTime()) | Boolean |
| Relative | Intl.RelativeTimeFormat | “2 days ago” |
Key takeaways:
- A
Dateis a single number — milliseconds since the Unix epoch - Month is 0-indexed — January is
0, December is11 getDay()returns 0–6 with Sunday as 0Date.now()is faster thannew Date().getTime()— use it for timestamps- Dates are mutable — copy with
new Date(d)before modifying ===compares references — usegetTime()or comparison operators-between dates gives milliseconds — divide by86400000for days- UTC avoids DST issues for date-only arithmetic
- String parsing is unreliable — prefer ISO 8601 or
Dateparts toISOString()is the safe, universal serialization formattoLocaleString()andIntl.DateTimeFormathandle displayIntl.RelativeTimeFormatgives “yesterday”, “in 2 hours”- Invalid Dates have
NaNtime — check withisNaN(d.getTime()) - Modern code should consider Temporal or libraries like date-fns for complex work
Remember: Date is quirky but unavoidable. Store dates as UTC milliseconds internally, format them for display only at the edges. Remember the 0-indexed month. Copy before mutating. Compare with getTime() or -. Use toISOString for serialization and toLocaleString for humans. Guard against Invalid Date. Master these rules, and JavaScript dates stop being a trap — they become a predictable tool.
Stop using slow, ad-bloated tool sites! 🤮
🔎 Search “KandZ Tools” on Google to use many professional utilities for free.
KandZ.me is the ultimate minimalist hub for:
✅ Finance (Mortgage, Interest, Inflation)
✅ Tech (Base64, JSON, Dev Suite, IP)
✅ Health (BMI, BMR, TDEE)
✅ Productivity (Timer, Workspace, QR)
⚡️ Fast & Private
🔒 No data leaves your device
💎 100% Free
🔗 Use it now: https://tools.kandz.me
🔖 Bookmark it—you’ll need it later!