The Definitive Guide to Date and Time in JavaScript

The Definitive Guide to Date and Time in JavaScript

JavaScript has lots to offer when it comes to Date and Time. You get plenty of handy methods, but some could be overwhelming. Let's learn them well.

Introduction

There are now nearly 9 million apps worldwide, and practically all of them run on an internal clock.

Financial apps are built on timestamped data. Office apps run on calendars. Social apps are defined by their feeds, timelines and anniversaries.

So, as devs, we need to know how to compute date and time. JavaScript, the world’s most popular programming language, has plenty of helpful APIs, but they can throw up complications if you’ve never used them before.

In this article we’re going to look into JavaScript Date, a standard built-in object for computing date and time. We’ll look at the issue of formatting, dive deep into its related aspects, and study the list of Date APIs in detail.

We’ll also look at the different use cases for JavaScript dates in programming, so you can see the challenges, as well as the benefits, in action.

Ready? Let’s Go.

JavaScript Date Object

Before we start talking about JavaScript, let’s have a quick history lesson.

The term Epoch refers to a specific point in time that happened in the past. In JavaScript, this is defined as midnight at the beginning of January 1, 1970, UTC (Coordinated Universal Time).

This snapshot serves as a reference-point for every single time-stamp in most development languages. In other words, we always refer back to this date as our own ‘Big Bang’ moment.

This referral process isn’t always user-friendly. However, JavaScript Date provides methods and properties to make it simpler.

You can use JavaScript Date to manipulate, format, and compare dates and times; convert between Date objects and epoch timestamps; and perform various other, more advanced operations.

The simplest way to create a Date object with today’s date in JavaScript is by using the new keyword.

const currentDate = new Date(); // Represents the current date and time

How do I create a JavaScript Date Object?

In JavaScript, you can create a Date object in several ways, according to your specific use cases.

Using the new Date() Constructor

The most common way to create a Date object is using the new Date() constructor or passing an argument to the Date() constructor.

This returns the current date and time in the local timezone when you do not pass any argument to it.

const date = new Date();
console.log(date);

This is the output (taken from my local computer at the moment of execution).

Sun Sep 10 2023 23:12:45 GMT+0530 (India Standard Time)

In these examples, we’ll use JavaScript’s console log. For expert tips about JavaScript console, check my article:

Advanced JavaScript Console Logging for Developers

Passing Individual Date Components

You can create a Date object by passing individual date and time components (year, month, day, hour, minute, second, and millisecond) as arguments to the constructor.

/**
 Let's understand the arguments passed.
 Starting from the left to right,
   - 2023 represents the Year
   - 8 represents the Month. It is an idex value starts 
     with 0 which repreents January month in the English
     calendar, 1 for February, and so on.
   - 10 represents the day between 1 to 31.
   - 23 represents the hour between 1 to 24.
   - 15 represents the minute.
   - 34 represents the second.
   - 0 represent the millisecond.

*/
const date = new Date(2023, 8, 10, 23, 15, 34, 0);
console.log(date);

So the output will be:

Sun Sep 10 2023 23:15:34 GMT+0530 (India Standard Time)

As the arguments are optional, you must be mindful of how the Date constructor behaves when we omit one or more arguments.

// Omitted seconds and milliseconds
console.log(new Date(2023, 8, 10, 23, 15)); // Sun Sep 10 2023 23:15:00

// Omitted hour, minute, seconds and milliseconds
console.log(new Date(2023, 8, 10)); // Sun Sep 10 2023 00:00:00

// Passed only Year and Month
console.log(new Date(2023, 8)); // Fri Sep 01 2023 00:00:00

// Attention Please!!!
console.log(new Date(2023)); // Thu Jan 01 1970 05:30:02

Parsing string to a JavaScript Date

You can create a Date object by passing a date and time string as an argument to the constructor. The string should be in a standardized date and time format.

const date = new Date("2013-09-10T13:24:00");
console.log(date); // Tue Sep 10 2013 13:24:00 GMT+0530 (India Standard Time)

A date-time representation, like the one we’ve used in the example below, is not standardized and it may only work in some of the environments.

// Discouraged to use a non-standardized format as
// an input to the new Date() contructor to create a Date object.

new Date("December 12, 2022 13:24:00");

Using Timestamps

You can create a Date Object by passing a timestamp, representing the total number of seconds (or even milliseconds), since the epoch snapshot (January 1, 1970).

const date = new Date(1688737100000);
console.log(date); // Fri Jul 07 2023 19:08:20 GMT+0530 (India Standard Time)

If you want to learn how to deal with Date and Time in Kotlin, you can checkout the following article:

Mastering Date and Time Handling in Kotlin for Android Developers

How do I get the current date in JavaScript?

When you work with dates, one of the standard requirements is to get the current date.

Without an argument, we have seen that the new Date() constructor returns the current date and time. But it returns a long date-time representation.

Thankfully, JavaScript provides multiple other ways to get the current date.

Current date using JavaScript Date Methods

With the Date Object, we can use methods like getFullYear(), getMonth(), and getDate() to get the current year, month, and date, respectively.

const date = new Date();

date.getFullYear(); // 2023
date.getMonth(); // 8
date.getDate(); // 11

We can now combine these methods to form the current date representation.

const date = new Date();

const day = date.getDate();
const month = date.getMonth() + 1; // The month index starts from 0
const year = date.getFullYear();

let currentDate = `${day}/${month}/${year}`;
console.log(currentDate); // 10/9/2023

A few things to note here:

  • You are free to change the date format the way you want. The above example outputs the date in the format dd/mm/yyyy. In case you want yyyy-mm-dd, you can use:
let currentDate = `${year}-${month}-${day}`;
  • The month as a single digit may not look great. In fact you probably want the date to look like 10/09/2023 than 10/9/2023. To tackle this, you can use the string method padStart(length, substring). It adds padding (with another string) to a given string until it reaches a specified length. To put 0 before 9, we have to pad the month string value with a “0” until it reaches length 2 and results in the string “09”.
const month = String(date.getMonth()+1).padStart(2,"0"); // Output "09"

The same applies to the date value.
Current date using the now() method

The Date.now() static method returns the current timestamp in milliseconds. This is the local time elapsed since the epoch.

We know that the Date constructor can create a Date object by passing the timestamp milliseconds as an argument. Hence, we can pass the Date.now() to the Date constructor to get the current date and time.

new Date(Date.now()); // Mon Sep 11 2023 08:01:44 GMT+0530 (India Standard Time)

If you are interested only in the date portion of the returned value, you can typecast the value to a string and use the slice method.

new String(new Date(Date.now())).slice(4, 15); // "Sep 11 2023"

Current Date using the toJSON() method

The toJSON() method of the Date object returns the current date and time in the date time string format. That is YYYY-MM-DDTHH:mm:ss.sssZ.

new Date().toJSON(); // "2023-09-11T02:41:56.619Z"

You can extract the current date value using the same slice method we applied before.

new Date().toJSON().slice(0, 10); // "2023-09-11"

Current Date using the toLocaleDateString() method

The simplest and most effective method to get the current date into a JavaScript string is using the toLocalDateString() method from the Date object.

const date = new Date().toLocaleDateString();
console.log(date); // "11/09/2023"

You can pass the locale as an argument to the toLocalDateStrung() method to get a locale-specific date. For example, to get the current date in the German locale, you can pass de-DE as the argument.

const date = new Date().toLocaleDateString("de-DE");
console.log(date); // 17.6.2022

There is a great tip to get the human-readable month name from the date object. I have an article on it. Please check it out:

The best way to get the month name from a date in JavaScript

How to calculate elapsed time using the JavaScript Date Object

To calculate the elapsed time between two dates in JavaScript, you can subtract one Date Object from another to get the difference in milliseconds and then convert that into the desired units (e.g., seconds, minutes, hours, or days).

// Define two Date objects representing the start and end dates
const startDate = new Date('2023-08-15T00:00:00');
const endDate = Date.now(); // Current date and time in milliseconds

// Calculate the time difference in milliseconds
const timeDifferenceMS = endDate - startDate;

// Calculate the elapsed time in seconds, minutes, hours, and days
const timeDifferenceSecs = Math.floor(timeDifferenceMS / 1000);
const timeDifferenceMins = Math.floor(timeDifferenceMS / 60000);
const timeDifferenceHours = Math.floor(timeDifferenceMS / 3600000);
const timeDifferenceDays = Math.floor(timeDifferenceMS / 86400000);

console.log(`Time difference in milliseconds: ${timeDifferenceMS}`);
console.log(`Time difference in seconds: ${timeDifferenceSecs}`);
console.log(`Time difference in minutes: ${timeDifferenceMins}`);
console.log(`Time difference in hours: ${timeDifferenceHours}`);
console.log(`Time difference in days: ${timeDifferenceDays}`);

Please note: Calculating the elapsed time between two dates in JavaScript, considering daylight saving time (DST), requires a bit more complexity because DST can affect the length of a day. You need an additional code to find the time differences between the two dates.

One way of calculating it, including the DST, will be like this:

// Get the time difference in milliseconds
let timeDifferenceMS = endTimestamp - startTimestamp;

// Check if either of the start or end date is in DST and
// adjust the DST offset accordingly.
if ((endDate.getTimezoneOffset() < startDate.getTimezoneOffset()) ||
    (startDate.getTimezoneOffset() < endDate.getTimezoneOffset() && startDate < endDate)) {
  // Adjust for the DST transition
  const dstTransition = endDate.getTimezoneOffset() - startDate.getTimezoneOffset();
  timeDifferenceMS -= dstTransition * 60 * 1000;
}

// Rest of the code is same as we have seen previously

JavaScript Date Formats

There are many ways we can format dates in JavaScript.

We have seen some of them while discussing how to create a Date object. However, the ECMAScript Internationalization(Intl) API provides a more flexible way to handle date-time format in JavaScript.

You can create language-sensitive (in other words, locale-aware) date and time using the Intl.DateTimeFormat API. When you do not specify a locale, the Intl.DateTimeFormat uses the default locale.

const date = new Date(Date.UTC(2023, 09, 17, 13, 1, 0));

// Format the date with the default locale, and the default time zone
console.log(new Intl.DateTimeFormat().format(date));

The above code will output “17/10/2023” when you run with en-US locale (language) and time zone IST (UTC+0530). When you need a localized date, you must explicitly pass it to the Intl.DateTimeFormat method.

const date = new Date(Date.UTC(2013, 09, 17, 13, 10, 20));

console.log("In en-US: ", new Intl.DateTimeFormat("en-US").format(date));

console.log("In en-GB: ", new Intl.DateTimeFormat("en-GB").format(date));

console.log("In ko-KR: ", new Intl.DateTimeFormat("ko-KR").format(date));

Here is the output:

In en-US:  10/17/2013
In en-GB:  17/10/2013
In ko-KR:  2013. 10. 17.

Passing an invalid/unsupported locale will fall back to the default locale.

const date = new Date(Date.UTC(2013, 09, 17, 13, 10, 20));
console.log(new Intl.DateTimeFormat(["xul", "id"]).format(date));

To give the following output:

17/10/2023

That’s not all. You can also pass options to the Intl.DateTimeFormat to get the desired formatted output.

Check out the code snippet below. We have passed the option to obtain the date in a format where a day is a numeric number, and the month name should be a long-formatted numeric year, and a long-formatted weekday. Also, we want this put out in the de-DE locale.

const date = new Date(Date.UTC(2023, 09, 17, 13, 10, 0, 200));

// request a weekday along with a long date
let options = {
  weekday: "long",
  year: "numeric",
  month: "long",
  day: "numeric",
};
console.log(new Intl.DateTimeFormat("de-DE", options).format(date));

Here’s the output:

Dienstag, 17. Oktober 2023

Please feel free to explore this API here.

Many popular JavaScript-based libraries have built wrappers over the JavaScript Date Object’s built-in methods to solve critical use cases.

It is impossible to list them all, but here are the top five versions I’ve used in the last few years.

  1. date-fns: date-fns is a modern JavaScript date utility library that provides a wide range of functions for formatting, parsing, manipulating, and comparing dates and times. It emphasizes simplicity and immutability.

  2. Moment.js:Moment.js was one of the most popular date libraries in the JavaScript ecosystem. It provides a comprehensive set of date manipulation and formatting functions. However, as of September 2020, it has been considered legacy, and its developers recommend using date-fns or luxon for new projects.

  3. Luxon: Luxon focuses on providing a clean API for parsing, formatting, and manipulating dates, while also considering internationalization and time zone support.

  4. Day.js: Day.js is a minimalist JavaScript library for date manipulation and formatting. It aims to be lightweight and easy to use, providing a simple API for common date tasks.

  5. timeago.js: timeago.js is a lightweight(~2KBs) nano library used to format date and time with time ago statement (e.g.: ‘2 hours ago’). It has support for React, Python, and plain JavaScript.

Temporal API

You must have realized by now that the JavaScript Date object is vast. There are a few shortcomings too.

  • We need more easy-to-use Date and Time APIs

  • The Date object doesn’t have support for non-Gregorian calendars.

  • Parsing a date from the string may not always give reliable results.

  • Computation for the DST is difficult.

  • The Date object lacks immutability.

The Temporal API, now in Stage 3 proposal, aims to solve all the problems we have pointed out above. You can read more about this proposal here.

As the Temporal API is in the experimental stage, it is not yet ready for production usage. If you want to try it out today, please install the polyfill.

npm install @js-temporal/polyfill

Then you can import it into your script file.

import { Temporal } from '@js-temporal/polyfill';

After that, you can start using the API methods.

const nowDate = Temporal.Now.plainDateISO()
const nowTime = Temporal.Now.plainTimeISO()

console.log(nowDate.toString())
// 2023-09-18
console.log(nowTime.toString())
// 13:18:41.576540798

To recap

  • JavaScript Date object has lots to offer. There are plenty of methods to deal with date, time, and their manipulations.

  • We can create JavaScript Date objects in various ways.

  • The methods provided to obtain day, month, year, and date are handy. However, the getMonth() method doesn’t return the month name directly.

  • The toLocaleDateString() is a much more precise and effective way to get locale-aware dates.

  • There are many ways to format date and time in JavaScript. ECMAScript’s Intl Date APIs provide the most flexible way to handle formatting.

  • We have popular date-time libraries to get and manipulate dates.

  • The Temporal Date API is a promising one to explore.

I hope the article was insightful and provided you with enough details to learn and explore the JavaScript Date object.

This article was Originally Published on Bugfender.

Bugfender is a log storage service for application developers. It collects everything happening in the application, even if it doesn’t crash, in order to reproduce and resolve bugs more effectively and provide better customer support. Get started with Bugfender from here.


Before We End...

That's all. Thanks for reading it. I hope it was insightful. If you liked the tutorial, please post likes and share it in your circles.

Let's connect. I share web development, content creation, Open Source, and career tips on these platforms.

Did you find this article valuable?

Support GreenRoots Blog - Tapas Adhikary by becoming a sponsor. Any amount is appreciated!