📌 Default Behavior
JavaScript uses the browser's local timezone
Display format example:
console.log(new Date().toString());
// Tue Jul 01 2025 12:30:25 GMT+0530 (India Standard Time)⚠️ Output will vary based on system time & timezone.
⚡️ Creating Date Objects
Date objects are created using:
new Date()
new Date(dateString)
new Date(year, month)
new Date(year, month, day)
new Date(year, month, day, hours)
new Date(year, month, day, hours, minutes)
new Date(year, month, day, hours, minutes, seconds)
new Date(year, month, day, hours, minutes, seconds, ms)
new Date(milliseconds)1) new Date()
Creates current date & time.
const d = new Date();
console.log(d.toString()); // Tue Jul 01 2025 12:30:25 GMT+0530 (India Standard Time)2) new Date(dateString)
Parses a valid date string.
const d = new Date("Feb 13, 2014 11:13:00");
console.log(d.toString()); // Thu Feb 13 2014 11:13:00 GMT+0530 (India Standard Time)⚠️ Note: parsing non-ISO formats can differ between browsers.
3) new Date(year, month, day, hour, minute, second, ms)
const d = new Date(2018, 11, 24, 10, 33, 30, 0);
console.log(d.toString()); // Mon Dec 24 2018 10:33:30 GMT+0530 (India Standard Time)✅ Month overflow example
Specifying a month higher than 11, will not result in an error but add the overflow to the next year.
const d = new Date(2018, 15, 24, 10, 33, 30, 0);
console.log(d.toString()); // Sun Apr 24 2019 10:33:30 GMT+0530 (India Standard Time)✅ Day overflow example
Specifying a day higher than max, will not result in an error but add the overflow to the next month.
const d = new Date(2018, 4, 35, 10, 33, 30, 0);
console.log(d.toString()); // Mon Jun 04 2018 10:33:30 GMT+0530 (India Standard Time)📌 JavaScript Stores Dates as Milliseconds
JavaScript stores dates as number of milliseconds since January 01, 1970.
🪄new Date(milliseconds)
new Date(*milliseconds*) creates a new date object as milliseconds plus zero time.
// 1 day = 24 * 60 * 60 * 1000 = 86400000 milliseconds
let nextDay = new Date(86400000); // Jan 2, 1970
let twoDaysLater = new Date(86400000 * 2); // Jan 3, 1970
let pastDate = new Date(-86400000); // Dec 31, 1969The number is relative to Jan 1, 1970.
Positive numbers = future dates.
Negative numbers = past dates.
const d = new Date(100000000000);
console.log(d.toString()); // Sat Mar 03 1973 15:16:40 GMT+0530 (India Standard Time)const d2 = new Date(-100000000000);
console.log(d2.toString()); // Mon Oct 31 1966 22:43:20 GMT+0530 (India Standard Time)<div class="infographic-datepg">
<style>
.infographic-datepg {
--ink: #1a1a1a;
--ink-soft: #5c5c5c;
--paper: #ffffff;
--paper-alt: #f0ece4;
--line: #ddd6c9;
--accent: #2563eb;
--accent-soft:#e3ebfd;
--ok: #1a7f4e;
--ok-soft: #e3f5ec;
--bad: #b42318;
--bad-soft: #fbe9e7;
--display-font: 'Fraunces', Georgia, serif;
--body-font: 'Inter', -apple-system, sans-serif;
--mono-font: 'IBM Plex Mono', 'Courier New', monospace;
margin: 0 auto;
box-sizing: border-box;
font-family: var(--body-font);
color: var(--ink);
background: var(--paper);
}
.infographic-datepg[data-theme="dark"] {
--ink: #e8e6e1;
--ink-soft: #9a968c;
--paper: #121212;
--paper-alt: #1e1e26;
--line: #2c313d;
--accent: #5b8def;
--accent-soft:#202942;
--ok: #5cd6a0;
--ok-soft: #16342a;
--bad: #e57373;
--bad-soft: #3a2222;
}
.infographic-datepg * { box-sizing: border-box; }
.infographic-datepg .ig-inner { padding: 1.75rem clamp(1.25rem, 5vw, 3rem) 2rem; }
.infographic-datepg .ig-title {
font-family: var(--display-font); font-size: clamp(1.4rem, 4.5vw, 1.9rem);
font-weight: 600; text-align: center; margin: 0 0 1.5rem;
}
.infographic-datepg .tabs { display: flex; gap: 0.4rem; justify-content: center; flex-wrap: wrap; }
.infographic-datepg .tab {
font: inherit; font-size: 0.78rem; font-weight: 600; border: 1px solid var(--line);
background: var(--paper); color: var(--ink-soft); padding: 0.4rem 0.8rem;
border-radius: 999px; cursor: pointer;
}
.infographic-datepg .tab.is-active { background: var(--accent); color: #fff; border-color: var(--accent); }
.infographic-datepg .panel { display: none; margin-top: 1.25rem; }
.infographic-datepg .panel.is-active { display: block; }
.infographic-datepg .code-block {
font-family: var(--mono-font); font-size: 0.78rem; line-height: 1.65;
background: #1e1e1e; color: #d4d4d4; border-radius: 6px;
padding: 0.8rem 1rem; white-space: pre; margin-bottom: 1rem;
box-shadow: 0 6px 16px rgba(0,0,0,0.2); overflow-x: auto;
}
.infographic-datepg .code-block .kw { color: #569cd6; font-weight: 700; }
.infographic-datepg .code-block .var { color: #9cdcfe; }
.infographic-datepg .code-block .method { color: #dcdcaa; }
.infographic-datepg .code-block .str { color: #ce9178; }
.infographic-datepg .code-block .num { color: #b5cea8; }
.infographic-datepg .code-block .comment { color: #6a9955; }
.infographic-datepg .inputs-row { display: flex; flex-wrap: wrap; gap: 0.6rem; justify-content: center; margin-bottom: 1rem; }
.infographic-datepg .field { display: flex; flex-direction: column; align-items: center; }
.infographic-datepg .field-tag { font-size: 0.62rem; font-family: var(--mono-font); color: var(--accent); margin-bottom: 0.3rem; }
.infographic-datepg .field input {
height: 2.3rem; font-family: var(--mono-font); font-size: 0.82rem; text-align: center;
border: 1px solid var(--line); background: var(--paper-alt); color: var(--ink); border-radius: 5px; outline: none;
padding: 0 0.4rem;
}
.infographic-datepg .field input:focus { border-color: var(--accent); }
.infographic-datepg .field.narrow input { width: 3.6rem; }
.infographic-datepg .field.wide input { width: 13rem; }
.infographic-datepg .field.mid input { width: 8rem; }
.infographic-datepg .preset-row { display: flex; gap: 0.4rem; justify-content: center; margin-bottom: 1rem; flex-wrap: wrap; }
.infographic-datepg .preset-btn {
font: inherit; font-size: 0.72rem; font-family: var(--mono-font); border: 1px dashed var(--line);
background: var(--paper); color: var(--ink-soft); padding: 0.3rem 0.6rem; border-radius: 4px; cursor: pointer;
}
.infographic-datepg .preset-btn:hover { border-color: var(--accent); color: var(--accent); }
.infographic-datepg .run-row { display: flex; justify-content: center; margin-bottom: 1rem; }
.infographic-datepg .run-btn {
font: inherit; font-size: 0.82rem; font-weight: 700; border: none; background: var(--accent);
color: #fff; padding: 0.5rem 1.2rem; border-radius: 999px; cursor: pointer;
}
.infographic-datepg .run-btn:hover { opacity: 0.9; }
.infographic-datepg .outcome {
border-radius: 6px; padding: 0.7rem 0.9rem; font-family: var(--mono-font); font-size: 0.8rem;
text-align: center; min-height: 1.3em; border: 1px solid var(--line); background: var(--paper-alt); color: var(--ink-soft);
word-break: break-word;
}
.infographic-datepg .outcome.is-live { border-color: var(--ok); background: var(--ok-soft); color: var(--ok); font-weight: 700; }
.infographic-datepg .outcome .why { display: block; margin-top: 0.3rem; font-size: 0.72rem; font-weight: 400; color: var(--ink-soft); }
@media (prefers-reduced-motion: reduce) {
.infographic-datepg *, .infographic-datepg *::before, .infographic-datepg *::after {
animation-duration: 0.001ms !important; transition-duration: 0.001ms !important;
}
}
</style>
<div class="ig-inner">
<h2 class="ig-title">JavaScript Date Playground</h2>
<div class="tabs" id="tabs">
<button class="tab is-active" data-panel="now">new Date()</button>
<button class="tab" data-panel="string">from string</button>
<button class="tab" data-panel="parts">from parts</button>
<button class="tab" data-panel="ms">from milliseconds</button>
</div>
<!-- NOW -->
<div class="panel is-active" id="panel-now">
<div class="code-block" id="code-now"><span class="kw">const</span> d = <span class="kw">new</span> <span class="method">Date</span>();
<span class="var">console</span>.<span class="method">log</span>(d.toString());</div>
<div class="run-row"><button class="run-btn" id="run-now">▶ Run</button></div>
<div class="outcome" id="out-now">shows your system's current date & time, in your local timezone</div>
</div>
<!-- STRING -->
<div class="panel" id="panel-string">
<div class="code-block" id="code-string"></div>
<div class="inputs-row">
<div class="field wide"><span class="field-tag">date string</span><input type="text" id="in-string" value="Feb 13, 2014 11:13:00"></div>
</div>
<div class="run-row"><button class="run-btn" id="run-string">▶ Run</button></div>
<div class="outcome" id="out-string">edit the string, then Run — non-ISO formats can parse differently across browsers</div>
</div>
<!-- PARTS -->
<div class="panel" id="panel-parts">
<div class="code-block" id="code-parts"></div>
<div class="inputs-row">
<div class="field narrow"><span class="field-tag">year</span><input type="number" id="p-year" value="2018"></div>
<div class="field narrow"><span class="field-tag">month</span><input type="number" id="p-month" value="11"></div>
<div class="field narrow"><span class="field-tag">day</span><input type="number" id="p-day" value="24"></div>
<div class="field narrow"><span class="field-tag">hour</span><input type="number" id="p-hour" value="10"></div>
<div class="field narrow"><span class="field-tag">min</span><input type="number" id="p-min" value="33"></div>
<div class="field narrow"><span class="field-tag">sec</span><input type="number" id="p-sec" value="30"></div>
</div>
<div class="preset-row">
<button class="preset-btn" data-preset="normal">normal</button>
<button class="preset-btn" data-preset="monthOverflow">month = 15 (overflow)</button>
<button class="preset-btn" data-preset="dayOverflow">day = 35 (overflow)</button>
</div>
<div class="run-row"><button class="run-btn" id="run-parts">▶ Run</button></div>
<div class="outcome" id="out-parts">month is 0-indexed (0=Jan) — try the overflow presets above</div>
</div>
<!-- MILLISECONDS -->
<div class="panel" id="panel-ms">
<div class="code-block" id="code-ms"></div>
<div class="inputs-row">
<div class="field mid"><span class="field-tag">milliseconds</span><input type="number" id="in-ms" value="86400000"></div>
</div>
<div class="preset-row">
<button class="preset-btn" data-preset-ms="86400000">+1 day</button>
<button class="preset-btn" data-preset-ms="172800000">+2 days</button>
<button class="preset-btn" data-preset-ms="-86400000">-1 day</button>
<button class="preset-btn" data-preset-ms="0">0 (epoch)</button>
</div>
<div class="run-row"><button class="run-btn" id="run-ms">▶ Run</button></div>
<div class="outcome" id="out-ms">dates are stored as ms since Jan 1, 1970 — positive = future, negative = past</div>
</div>
</div>
</div>
<script>
(function () {
const wrapper = document.currentScript.closest('.infographic-datepg')
|| document.querySelector('.infographic-datepg');
const bodyAttr = document.body.getAttribute('data-darkmode');
let dark;
if (bodyAttr === 'true') {
dark = true;
} else if (bodyAttr === 'false') {
dark = false;
} else {
const match = document.cookie.match(/(?:^|;\s*)darkMode=([^;]+)/);
dark = match ? match[1] === 'true' : false;
}
if (dark) wrapper.setAttribute('data-theme', 'dark');
// Tabs
const tabs = wrapper.querySelectorAll('.tab');
const panels = {
now: wrapper.querySelector('#panel-now'),
string: wrapper.querySelector('#panel-string'),
parts: wrapper.querySelector('#panel-parts'),
ms: wrapper.querySelector('#panel-ms')
};
tabs.forEach(tab => {
tab.addEventListener('click', () => {
tabs.forEach(t => t.classList.toggle('is-active', t === tab));
Object.entries(panels).forEach(([k, el]) => el.classList.toggle('is-active', k === tab.dataset.panel));
});
});
// NOW
wrapper.querySelector('#run-now').addEventListener('click', () => {
const out = wrapper.querySelector('#out-now');
out.className = 'outcome is-live';
out.textContent = new Date().toString();
});
// STRING
const codeString = wrapper.querySelector('#code-string');
const inString = wrapper.querySelector('#in-string');
function renderString() {
codeString.innerHTML =
`<span class="kw">const</span> d = <span class="kw">new</span> <span class="method">Date</span>(<span class="str">"${inString.value}"</span>);
<span class="var">console</span>.<span class="method">log</span>(d.toString());`;
}
inString.addEventListener('input', renderString);
renderString();
wrapper.querySelector('#run-string').addEventListener('click', () => {
const out = wrapper.querySelector('#out-string');
const d = new Date(inString.value);
if (isNaN(d.getTime())) {
out.className = 'outcome';
out.innerHTML = `Invalid Date<span class="why">this string couldn't be parsed</span>`;
return;
}
out.className = 'outcome is-live';
out.textContent = d.toString();
});
// PARTS
const codeParts = wrapper.querySelector('#code-parts');
const pYear = wrapper.querySelector('#p-year');
const pMonth = wrapper.querySelector('#p-month');
const pDay = wrapper.querySelector('#p-day');
const pHour = wrapper.querySelector('#p-hour');
const pMin = wrapper.querySelector('#p-min');
const pSec = wrapper.querySelector('#p-sec');
const partsInputs = [pYear, pMonth, pDay, pHour, pMin, pSec];
function renderParts() {
codeParts.innerHTML =
`<span class="kw">const</span> d = <span class="kw">new</span> <span class="method">Date</span>(<span class="num">${pYear.value}</span>, <span class="num">${pMonth.value}</span>, <span class="num">${pDay.value}</span>, <span class="num">${pHour.value}</span>, <span class="num">${pMin.value}</span>, <span class="num">${pSec.value}</span>, <span class="num">0</span>);
<span class="var">console</span>.<span class="method">log</span>(d.toString()); <span class="comment">// month is 0-indexed</span>`;
}
partsInputs.forEach(inp => inp.addEventListener('input', renderParts));
renderParts();
wrapper.querySelectorAll('[data-preset]').forEach(btn => {
btn.addEventListener('click', () => {
const preset = btn.dataset.preset;
if (preset === 'normal') { pYear.value = 2018; pMonth.value = 11; pDay.value = 24; pHour.value = 10; pMin.value = 33; pSec.value = 30; }
if (preset === 'monthOverflow') { pYear.value = 2018; pMonth.value = 15; pDay.value = 24; pHour.value = 10; pMin.value = 33; pSec.value = 30; }
if (preset === 'dayOverflow') { pYear.value = 2018; pMonth.value = 4; pDay.value = 35; pHour.value = 10; pMin.value = 33; pSec.value = 30; }
renderParts();
});
});
wrapper.querySelector('#run-parts').addEventListener('click', () => {
const out = wrapper.querySelector('#out-parts');
const y = Number(pYear.value), mo = Number(pMonth.value), da = Number(pDay.value);
const h = Number(pHour.value), mi = Number(pMin.value), se = Number(pSec.value);
const d = new Date(y, mo, da, h, mi, se, 0);
out.className = 'outcome is-live';
let why = '';
if (mo > 11) why = `month ${mo} overflowed into ${d.toLocaleString('en-US', { month: 'long' })} ${d.getFullYear()}`;
else if (da > new Date(y, mo + 1, 0).getDate()) why = `day ${da} overflowed into the next month`;
out.innerHTML = d.toString() + (why ? `<span class="why">${why}</span>` : '');
});
// MILLISECONDS
const codeMs = wrapper.querySelector('#code-ms');
const inMs = wrapper.querySelector('#in-ms');
function renderMs() {
codeMs.innerHTML =
`<span class="kw">const</span> d = <span class="kw">new</span> <span class="method">Date</span>(<span class="num">${inMs.value}</span>);
<span class="var">console</span>.<span class="method">log</span>(d.toString());`;
}
inMs.addEventListener('input', renderMs);
renderMs();
wrapper.querySelectorAll('[data-preset-ms]').forEach(btn => {
btn.addEventListener('click', () => {
inMs.value = btn.dataset.presetMs;
renderMs();
});
});
wrapper.querySelector('#run-ms').addEventListener('click', () => {
const out = wrapper.querySelector('#out-ms');
const ms = Number(inMs.value) || 0;
const d = new Date(ms);
out.className = 'outcome is-live';
const rel = ms === 0 ? 'exactly the epoch' : (ms > 0 ? `${ms}ms after Jan 1, 1970` : `${Math.abs(ms)}ms before Jan 1, 1970`);
out.innerHTML = d.toString() + `<span class="why">${rel}</span>`;
});
})();
</script>.demo {
font-family: system-ui, sans-serif;
padding: 16px;
}
.demo h1 {
color: #2563eb;
margin: 0 0 8px;
}
.demo p {
color: #4b5563;
margin: 0;
}document.querySelector('.demo h1')?.addEventListener('click', () => {
alert('Hello from live preview!');
});