JavaScript
Date Formatting
Programming
Web Development
Coding Techniques

Format JavaScript date as yyyy-mm-dd

Interview Questions practice on Codemia

Over 8,000 real interview questions from top companies, searchable by company and role.

Browse interview questions

Introduction

Formatting a JavaScript Date as yyyy-mm-dd is simple once you decide whether you mean local calendar date or UTC date. That choice matters, because the same instant can format to different dates depending on the time zone you use.

For many applications, a small helper using getFullYear, getMonth, and getDate is enough. If you want ISO-style UTC output from an existing Date, toISOString() can also be useful, but only when UTC semantics are actually correct for the problem.

Format a Local Date Manually

If the string should represent the user's local calendar date, build it from the local date parts:

javascript
1function formatDate(date) {
2  const year = date.getFullYear();
3  const month = String(date.getMonth() + 1).padStart(2, "0");
4  const day = String(date.getDate()).padStart(2, "0");
5
6  return `${year}-${month}-${day}`;
7}
8
9console.log(formatDate(new Date()));

This is the clearest solution when the date should follow local time.

Use UTC Only When You Actually Want UTC

If the date string should be based on UTC, use the UTC accessors instead:

javascript
1function formatDateUTC(date) {
2  const year = date.getUTCFullYear();
3  const month = String(date.getUTCMonth() + 1).padStart(2, "0");
4  const day = String(date.getUTCDate()).padStart(2, "0");
5
6  return `${year}-${month}-${day}`;
7}
8
9console.log(formatDateUTC(new Date()));

The difference can matter around midnight or when users are in different time zones.

toISOString() Is Convenient but Not Neutral

You will often see:

javascript
const value = new Date().toISOString().slice(0, 10);
console.log(value);

This works, but it formats the date in UTC, not local time. That is fine for some APIs and storage formats, but it is wrong if the requirement is "today according to the user's locale."

So the shortcut is convenient, but only when UTC is the intended calendar.

Why Padding Matters

Without padding, months and days below 10 produce uneven output such as 2025-1-5. If the format really needs yyyy-mm-dd, pad both fields to two digits:

javascript
String(date.getMonth() + 1).padStart(2, "0");
String(date.getDate()).padStart(2, "0");

That keeps sorting and display consistent.

A Reusable Utility

If the application needs both local and UTC formatting, make the difference explicit:

javascript
1function formatYyyyMmDd(date, { utc = false } = {}) {
2  const year = utc ? date.getUTCFullYear() : date.getFullYear();
3  const month = String(
4    (utc ? date.getUTCMonth() : date.getMonth()) + 1
5  ).padStart(2, "0");
6  const day = String(
7    utc ? date.getUTCDate() : date.getDate()
8  ).padStart(2, "0");
9
10  return `${year}-${month}-${day}`;
11}
12
13console.log(formatYyyyMmDd(new Date()));
14console.log(formatYyyyMmDd(new Date(), { utc: true }));

This makes the time-zone policy visible at the call site instead of burying it inside a helper with ambiguous behavior.

Common Pitfalls

The biggest mistake is using toISOString().slice(0, 10) when the real requirement is a local date. That silently converts the date to UTC and can shift the day.

Another common issue is forgetting that JavaScript months are zero-based in getMonth(). You must add one before formatting.

Developers also sometimes skip zero-padding and end up with strings that do not match the required format exactly.

Finally, avoid depending on locale-based formatting APIs when you specifically need the stable machine-readable pattern yyyy-mm-dd. Locale formatters are for display, not for fixed-format output contracts.

That distinction becomes especially important when the formatted value is stored, sorted, or sent to another system.

Summary

  • Build yyyy-mm-dd manually from Date parts when you need clear control.
  • Use local getters for local calendar dates and UTC getters for UTC dates.
  • 'toISOString().slice(0, 10) is convenient, but it always uses UTC.'
  • Zero-pad the month and day to keep the format stable.
  • Decide the time-zone rule first, then choose the formatting approach that matches it.

Related reading
Free course
Beginner
7 lessons
2 hours
Tackling System Design Interview Problems

A short course that equips you with the skills to approach system design interviews methodically.

Start the free course
Track what you have practised

A free account saves your progress, solutions and study plan across every problem on Codemia.

Interview Questions practice on Codemia

Over 8,000 real interview questions from top companies, searchable by company and role.

Browse interview questions

All Rights Reserved.