Learn
🤖 AI Hub 📰 News 📖 Dictionary 🧰 Resources
Grow
💼 Jobs 🚀 Community 🏆 Challenges
Explore by Stage
🌑 Zero 📚 Learn 🔧 Practice 🏗 Build 🚀 Launch 💰 Earn
Account
Login Sign Up
🏗️HTML 🎨CSS ⚡JavaScript 🐙Git & GitHub ⚛️React Soon 📘TypeScript Soon 🐍Python 🗄️Database & SQL Soon 🌐Web Development Soon ☁️Cloud & DevOps Soon 🤖AI & ML Soon 📄Resume Prep Soon 🎤Interview Prep Soon 💼Freelancing Soon 🚀SaaS & Side Projects Soon 🤖Automation Soon
Intermediate 🕑 13 min read 👁 2 views 📅 Oct 21, 2026

Dates and Time: Countdowns, Ages and Formatting

Create and change dates, find the days between two dates, format dates the Indian way and handle IST and UTC. Build a live board exam countdown and a scholarship age calculator.

Why Dates Matter: Exams, Forms and Deadlines

Think of the apps you use around exam time. A study app shows “117 days left for the board exams”. A scholarship form says “You must be under 18 on 1 April”. A coaching centre site shows the last date to pay fees. Behind each of these is JavaScript working with dates.

In this lesson you will build two such tools: a live countdown to the board exams and an age calculator for a scholarship form. On the way you will learn how to create dates, read and change their parts, do date maths, show dates the Indian way and handle time zones.

JavaScript keeps every date as one number: the milliseconds since 1 January 1970 (UTC). You rarely see this number, but it explains why date maths works so simply, as you will see.

Creating Dates

You create a date with new Date(...). There are three common ways:

  • new Date() with nothing inside gives the current date and time.
  • new Date(year, month, day, hours, minutes) builds a date from parts.
  • new Date("2027-02-15T10:30:00") reads a date from an ISO string. ISO is an international standard format: year, month, day, then the letter T, then the time.
// 1. Right now: the date and time on the learner's device
const now = new Date();
console.log(now.getFullYear());   // the current year, for example 2026

// 2. From parts: year, month, day, hour, minute
// Careful: months start at 0, so 1 means February!
const firstExam = new Date(2027, 1, 15, 10, 30);
console.log(firstExam.toDateString());   // Mon Feb 15 2027

// 3. From an ISO string: "YYYY-MM-DDTHH:MM:SS"
const fromText = new Date("2027-02-15T10:30:00");
console.log(fromText.toDateString());    // Mon Feb 15 2027
console.log(fromText.getHours());        // 10

The most famous trap in JavaScript dates: when you build a date from parts, months start at 0. January is 0, February is 1 and December is 11. Days of the month start at 1 as normal. In an ISO string, months are normal (02 is February). So new Date(2027, 1, 15) and "2027-02-15" both mean 15 February.

Whose clock? new Date() reads the clock and time zone of the device that runs the code. In the browser, that is the visitor’s phone or laptop. On a server, it is the server’s clock, which is often set to UTC. Keep this in mind for the time zone section below.

Getters and Setters

A date object has getter methods to read one part and setter methods to change one part. Their names are easy to guess: getFullYear() and setFullYear(), getHours() and setHours(), and so on.

const exam = new Date(2027, 1, 15, 10, 30);

// Getters: read one part of the date
console.log(exam.getFullYear());  // 2027
console.log(exam.getMonth());     // 1   (February, because January is 0)
console.log(exam.getDate());      // 15  (day of the month)
console.log(exam.getDay());       // 1   (day of the week: 0 is Sunday, 1 is Monday)
console.log(exam.getHours());     // 10
console.log(exam.getMinutes());   // 30

// Setters: change one part of the date
exam.setHours(14);                // the exam moves to the afternoon
exam.setMinutes(0);
console.log(exam.getHours(), exam.getMinutes());  // 14 0
GetterWhat it returnsRange
getFullYear()The yearfor example 2027
getMonth()The month0 (January) to 11 (December)
getDate()The day of the month1 to 31
getDay()The day of the week0 (Sunday) to 6 (Saturday)
getHours(), getMinutes(), getSeconds()The time0 to 23, 0 to 59, 0 to 59

Do not mix up getDate() (day of the month) and getDay() (day of the week). Many bugs come from this one letter.

Adding Days to a Date

Suppose a form says “submit your documents within 10 days”. To find the last date, read the day with getDate(), add 10 and set it back with setDate(). If the new day is beyond the end of the month, JavaScript moves into the next month (and even the next year) for you.

function addDays(date, days) {
  const copy = new Date(date);          // copy first, so the original stays the same
  copy.setDate(copy.getDate() + days);
  return copy;
}

const formFilled = new Date(2026, 4, 28);      // 28 May 2026
const lastDate = addDays(formFilled, 10);

console.log(formFilled.toDateString());  // Thu May 28 2026  (unchanged)
console.log(lastDate.toDateString());    // Sun Jun 07 2026  (moved into June by itself)

Setters change the original date object. That is why addDays makes a copy first with new Date(date). Without the copy, the form date would also change, which is a confusing bug.

The Difference Between Two Dates

Because a date is really a number of milliseconds, you can subtract one date from another. The answer is in milliseconds. Divide by the number of milliseconds in a day to get days.

const MS_PER_DAY = 1000 * 60 * 60 * 24;   // 86,400,000 milliseconds

function daysBetween(from, to) {
  return Math.round((to - from) / MS_PER_DAY);
}

const today = new Date(2026, 9, 21);       // 21 October 2026
const boardExam = new Date(2027, 1, 15);   // 15 February 2027

console.log(boardExam - today);               // 10108800000 (milliseconds)
console.log(daysBetween(today, boardExam));   // 117

We use Math.round because in countries with daylight saving time, one day in the year has 23 hours and another has 25. India does not change its clocks, but your website may have visitors from other countries, so rounding keeps the answer correct everywhere.

Formatting Dates the Indian Way

In India we write the day first: 15/2/2027, not 2/15/2027 as in the USA. Never build date text by hand. Use toLocaleDateString() and toLocaleTimeString() with the locale "en-IN" (English, India). A locale is a language and region code that tells the browser how people there write dates and numbers. The second argument is an options object that chooses which parts to show and how.

const exam = new Date(2027, 1, 15, 10, 30);

console.log(exam.toLocaleDateString("en-IN"));
// 15/2/2027

console.log(exam.toLocaleDateString("en-IN", {
  weekday: "long", day: "numeric", month: "long", year: "numeric"
}));
// Monday, 15 February 2027

console.log(exam.toLocaleDateString("en-IN", { day: "2-digit", month: "short", year: "numeric" }));
// 15 Feb 2027

console.log(exam.toLocaleTimeString("en-IN", { hour: "2-digit", minute: "2-digit" }));
// 10:30 am

// Intl.DateTimeFormat: create the formatter once, use it many times
const shortDate = new Intl.DateTimeFormat("en-IN", { day: "numeric", month: "short" });
const papers = [new Date(2027, 1, 15), new Date(2027, 1, 18), new Date(2027, 1, 22)];
papers.forEach(function (d) {
  console.log(shortDate.format(d));
});
// 15 Feb
// 18 Feb
// 22 Feb

// The same date in Hindi
console.log(new Intl.DateTimeFormat("hi-IN", { dateStyle: "full" }).format(exam));
// सोमवार, 15 फ़रवरी 2027

Intl.DateTimeFormat is the engine behind toLocaleDateString(). When you format many dates, such as a full exam timetable, create one formatter and reuse it. It is faster and keeps all your dates looking the same. Try "ta-IN" (Tamil) or "bn-IN" (Bengali) instead of "hi-IN".

OptionCommon valuesExample output
weekday"long", "short"Monday, Mon
day"numeric", "2-digit"5, 05
month"long", "short", "numeric"February, Feb, 2
hour, minute"numeric", "2-digit"10:30 am

Small differences between browsers are normal, for example “am” or “AM”. Do not write code that depends on the exact text.

Printing a date: in the Try it yourself console, always print a date with a method such as toDateString() or toLocaleDateString(). A plain console.log(date) can look different in every browser.

Time Zones: IST, UTC and the Server

India Standard Time (IST) is UTC + 5:30. UTC is the world’s reference time. When it is 4:30 AM in UTC, it is 10:00 AM in India.

This matters because your code runs in two places. The browser uses the visitor’s time zone. A server often runs in UTC. If a server creates “today” at 2:00 AM in India, the server may still think it is yesterday. The safe habit is:

  1. Store and send times in UTC, as ISO strings ending in Z (you get one with toISOString()).
  2. Convert to local time only when you show the time to a person.
// The "Z" at the end means UTC time
const resultTime = new Date("2027-05-10T04:30:00Z");

console.log(resultTime.toISOString());
// 2027-05-10T04:30:00.000Z

console.log(resultTime.toLocaleString("en-IN", { timeZone: "Asia/Kolkata" }));
// 10/5/2027, 10:00:00 am   (IST is UTC + 5:30)

console.log(resultTime.toLocaleString("en-IN", { timeZone: "Asia/Dubai" }));
// 10/5/2027, 8:30:00 am    (for a cousin who works in Dubai)

// Minutes between UTC and this device's time zone
console.log(new Date().getTimezoneOffset());
// -330 on a device set to India time

The timeZone option lets you show any time zone, no matter where the code runs. "Asia/Kolkata" is the official name for IST.

Real-Life Example: A Live Board Exam Countdown

Ananya is in Class 12. She wants a page on her laptop that shows exactly how long is left before her first board paper. The page uses everything above: a date from parts, formatting with en-IN, the difference between two dates, and setInterval, which runs a function again and again after a fixed number of milliseconds (here every 1000 ms, which is one second).

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>Board Exam Countdown</title>
  <style>
    body { font-family: sans-serif; text-align: center; padding: 20px; }
    #timer { font-size: 2rem; font-weight: bold; color: #1a56db; }
  </style>
</head>
<body>
  <h2>Class 12 Board Exams</h2>
  <p id="examDate"></p>
  <p id="timer">Loading...</p>
  <p id="message">Every day of revision counts. You can do this!</p>

  <script>
    // Change this to your own exam date and time
    const examStart = new Date(2027, 1, 15, 10, 30);   // 15 February 2027, 10:30 AM

    document.getElementById("examDate").textContent =
      "First paper: " + examStart.toLocaleDateString("en-IN", {
        weekday: "long", day: "numeric", month: "long", year: "numeric"
      }) + " at " + examStart.toLocaleTimeString("en-IN", { hour: "2-digit", minute: "2-digit" });

    function updateTimer() {
      const msLeft = examStart - new Date();

      if (msLeft <= 0) {
        document.getElementById("timer").textContent = "The exam has started. All the best!";
        clearInterval(timerId);
        return;
      }

      const totalSeconds = Math.floor(msLeft / 1000);
      const days = Math.floor(totalSeconds / 86400);
      const hours = Math.floor((totalSeconds % 86400) / 3600);
      const minutes = Math.floor((totalSeconds % 3600) / 60);
      const seconds = totalSeconds % 60;

      document.getElementById("timer").textContent =
        days + " days " + hours + " h " + minutes + " min " + seconds + " s";
    }

    const timerId = setInterval(updateTimer, 1000);  // update every second
    updateTimer();                                   // and show the time at once
  </script>
</body>
</html>

The function turns the milliseconds left into days, hours, minutes and seconds with division and the remainder operator %. When the time is up, clearInterval stops the timer so it does not keep running for nothing.

Try these changes:

  1. Change examStart to a time two minutes from now and watch the message change when it reaches zero.
  2. Show only days and hours, for a calmer countdown.
  3. Add a second line that counts down to the last paper of the timetable.

Common Mistakes

  • Forgetting that months start at 0. new Date(2027, 2, 15) is 15 March, not 15 February. Fix: subtract 1 from the month, or use an ISO string.
  • Using getDay() when you mean getDate(). getDay() gives the weekday (0 to 6). Fix: use getDate() for the day of the month.
  • Changing the original date by mistake. Setters change the object itself. Fix: copy it with new Date(original) first.
  • Reading a date-only string as local time. new Date("2026-03-15") is read as midnight UTC, which is 5:30 AM in India and still the 14th in some countries. This often happens with the value of an <input type="date">. Fix: add a time, as shown below.
// A date-only ISO string is read as midnight UTC, not midnight in India
const a = new Date("2026-03-15");
console.log(a.getHours());   // 5  (5:30 AM in India, because UTC midnight is 5:30 AM IST)

// Add a time (without "Z") and it is read as local time
const b = new Date("2026-03-15T00:00:00");
console.log(b.getHours());   // 0

Practice Task: Scholarship Age Calculator

A state merit scholarship is open only to students who are under 18 on 1 April 2027. Complete the starter page so that a student can choose a date of birth and see whether they can apply.

  • Write ageOn(birth, onDate) that returns the age in full years on a given date.
  • Remember: if the birthday has not come yet in that year, the person is one year younger.
  • Show a friendly message if no date is chosen.
  • Read the date input value as a local date.
  • Show the cut-off date in Indian format, for example “1 April 2027”.
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>Scholarship Age Check</title>
</head>
<body>
  <h2>Merit Scholarship: Age Check</h2>
  <p>Applicants must be under 18 years of age on 1 April 2027.</p>

  <label for="dob">Date of birth</label>
  <input type="date" id="dob">
  <button id="check">Check</button>
  <p id="result"></p>

  <script>
    const cutOff = new Date(2027, 3, 1);   // 1 April 2027

    function ageOn(birth, onDate) {
      // TODO 1: start with the difference between the two years
      // TODO 2: subtract 1 if the birthday has not come yet in that year
    }

    document.getElementById("check").addEventListener("click", function () {
      const value = document.getElementById("dob").value;   // for example "2009-08-20"
      // TODO 3: if value is empty, ask the student to choose a date
      // TODO 4: turn value into a local date (add "T00:00:00")
      // TODO 5: show the age and whether the student can apply
    });
  </script>
</body>
</html>
Show one possible answer (try it yourself first!)
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>Scholarship Age Check</title>
</head>
<body>
  <h2>Merit Scholarship: Age Check</h2>
  <p>Applicants must be under 18 years of age on 1 April 2027.</p>

  <label for="dob">Date of birth</label>
  <input type="date" id="dob">
  <button id="check">Check</button>
  <p id="result"></p>

  <script>
    const cutOff = new Date(2027, 3, 1);   // 1 April 2027

    function ageOn(birth, onDate) {
      let age = onDate.getFullYear() - birth.getFullYear();
      const birthdayPassed =
        onDate.getMonth() > birth.getMonth() ||
        (onDate.getMonth() === birth.getMonth() && onDate.getDate() >= birth.getDate());
      if (!birthdayPassed) {
        age = age - 1;
      }
      return age;
    }

    document.getElementById("check").addEventListener("click", function () {
      const value = document.getElementById("dob").value;
      const result = document.getElementById("result");

      if (value === "") {
        result.textContent = "Please choose your date of birth first.";
        return;
      }

      const birth = new Date(value + "T00:00:00");
      const age = ageOn(birth, cutOff);
      const cutOffText = cutOff.toLocaleDateString("en-IN", { day: "numeric", month: "long", year: "numeric" });

      if (age < 18) {
        result.textContent = "You will be " + age + " on " + cutOffText + ". You can apply!";
      } else {
        result.textContent = "You will be " + age + " on " + cutOffText + ". Sorry, the age limit is under 18.";
      }
    });
  </script>
</body>
</html>

Key Takeaways

  • Create dates with new Date(), from parts (months start at 0) or from an ISO string.
  • Use getters and setters to read and change parts, and copy a date before you change it.
  • Subtracting dates gives milliseconds; divide by 1000 * 60 * 60 * 24 for days.
  • Show dates with toLocaleDateString("en-IN", options) or a reusable Intl.DateTimeFormat.
  • IST is UTC + 5:30. Store times in UTC and convert to local time only for display.
  • setInterval with clearInterval makes a live countdown.

❓ Frequently Asked Questions

It copied this rule from older languages, where months were used as positions in a list of month names. It cannot change now without breaking old websites, so remember that 0 is January and 11 is December when you build a date from parts.
It is only as correct as the clock on the device. A visitor can set the wrong time on their phone, so for important deadlines such as exam form closing times, the server must check the time too.
For most small projects, the built-in Date object and Intl.DateTimeFormat are enough. Bigger apps with many time zones sometimes use a library, and JavaScript is also adding a newer built-in API called Temporal that some modern browsers already support.
Pass a different locale, such as hi-IN for Hindi or ta-IN for Tamil, to toLocaleDateString or Intl.DateTimeFormat. The browser translates the month and weekday names for you.
Was this lesson helpful?

🎯 Finished this lesson?

🔗 Related Tutorials
🤖 Got a Doubt? Ask AI
Get instant answers in Hindi or English
🤖
Z2T Bot
Online
Ask me anything about this tutorial — I'm here! 👋