Guide to Dates in JavaScript, plus making it easier with date-fns

Guide to Dates in JavaScript, plus making it easier with date-fns

It is extremely common to have to work with dates while developing software. If you're new to programming, or maybe just new to programming with JavaScript, you may have a couple of questions on your mind when it comes to working with dates:

  • How do dates work in JavaScript?

  • How do I convert strings to dates?

  • How do I format dates easily? More specifically, how would one easily convert January 1st, 2001 to 01/01/01?

By the end of this article, hopefully you will be able to answer these questions yourself!


The JavaScript Date Object

In JavaScript, you will use the Date object to work with dates and times. The Date object provides methods to create, manipulate, and format dates and times!

Let's look at creating a new date:

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

The code above will create a new Date object for the current date and time. The exact output of this code may vary depending on environment, but it will be something similar to:

2024-07-07T00:56:48.176Z

This output indicates the current date and time in the ISO 8601 format (in the UTC time zone).

The Epoch

Before moving on to more code-related features of the Date object, let's talk about some background on how the Date object works.

JavaScript Dates are defined by the time in milliseconds that have elapsed since the epoch (the midnight at the beginning of January 1st, 1970 UTC). These timestamps are thus timezone-agnostic. Since all Dates are defined relative to the epoch, each uniquely defines an instant in time.

As far as boundaries go, the max timestamp representable by a Date object is slightly smaller than the maximum safe integer (which is more than 9 quadrillion). This means that a Date object can represent a moment in time from April 20, 271821 BC to September 13th, 275760 AD. If you try to specify a Date object outside of this (quite large) range, then it will hold a timestamp value of NaN, not very ideal.

Creating Dates

As we saw earlier, if you don't pass anything into the Date constructor, it will create a Date with the current timestamp. But of course, there are many other use cases of the Date object.

Milliseconds since Epoch

You can create a Date object by passing the number of milliseconds since the epoch.

let dateFromMilliseconds = new Date(1400000000000);
console.log(dateFromMilliseconds); // Sat May 13 2014 16:53:20 GMT+0000 (UTC)

Date String

For a much more practical approach, you can create a Date object from a string. The date string can be in various formats, but the ISO 8601 format is recommended for consistency.

let dateFromString = new Date("2024-07-06T12:30:00Z");
console.log(dateFromString); // Sat Jul 06 2024 12:30:00 GMT+0000 (UTC)

To read more about the ISO 8601 format, click here:

ISO 8601 - iso.org

Using Year, Month, Day, Hours, Minutes, Seconds, Milliseconds

As the title suggests, you can also create a Date object with the specified values for Year, Month, Day, Hours, Minutes, Seconds, Milliseconds. Note that the month is 0-indexed, which means January is 0, and December is 11!

let specificDate = new Date(2024, 6, 6, 12, 30, 0, 0); // July 6, 2024, 12:30:00
console.log(specificDate); // Sat Jul 06 2024 12:30:00 GMT+0000 (UTC)

Note that when you leave some fields blank, the omitted fields will default to zero. For example, if you leave out minutes, seconds, and milliseconds, they will default to 0.

let specificDate = new Date(2024, 6, 6, 12);
console.log(specificDate);

This will create a Date object whose timestamp represents July 6th, 2024, at 12:00:00.


Getting Components of a Date Object

Here's how you can get specific components of your Date object:

let now = new Date();

let year = now.getFullYear(); // 2024
let month = now.getMonth(); // 0-11 (January is 0)
let day = now.getDate(); // 1-31
let hours = now.getHours(); // 0-23
let minutes = now.getMinutes(); // 0-59
let seconds = now.getSeconds(); // 0-59
let milliseconds = now.getMilliseconds(); // 0-999

You can also get the day of the week, which will return a number 0 to 6, with Sunday being 0, and Saturday being 6.

let dayOfWeek = now.getDay(); // 0-6 (Sunday is 0, Saturday is 6)

You can also get UTC components:

let utcYear = now.getUTCFullYear();
let utcMonth = now.getUTCMonth();
let utcDate = now.getUTCDate();
let utcHours = now.getUTCHours();
let utcMinutes = now.getUTCMinutes();
let utcSeconds = now.getUTCSeconds();
let utcMilliseconds = now.getUTCMilliseconds();

Manipulating Components in a Date Object

To set the different components of the timestamp of your date, you can do:

now.setFullYear(2025);
now.setMonth(11); // December
now.setDate(25); // 25th day
now.setHours(15); // 3 PM
now.setMinutes(45);
now.setSeconds(30);
now.setMilliseconds(500);

You can also set the UTC components:

now.setUTCFullYear(2025);
now.setUTCMonth(11);
now.setUTCDate(25);
now.setUTCHours(15);
now.setUTCMinutes(45);
now.setUTCSeconds(30);
now.setUTCMilliseconds(500);

Adding and Subtracting Time

A lot of the time, you will need to mutate dates to a new value that is relative to the old one. For example, your calendar picker component may need to disable days that are too old or too far in the future relative to the current date, so you'll need to calculate those values to set as the bounds.

Here, we can use getDate and setDate to add or subtract days to the current date:

let newDate = new Date(now);
newDate.setDate(newDate.getDate() + 5); // Add 5 days
let newDate = new Date(now);
newDate.setDate(newDate.getDate() - 5); // Subtract 5 days

Of course, you can do this with months and years as well:

let newDate = new Date(now);
newDate.setMonth(newDate.getMonth() + 1); // Add 1 month
let newDate = new Date(now);
newDate.setFullYear(newDate.getFullYear() + 1); // Add 1 year

Comparing Dates

A very important thing you'll need to do with dates is compare them.

You can directly compare two Date object like so:

let date1 = new Date('2024-07-06');
let date2 = new Date('2024-07-07');

if (date1 < date2) {
    console.log("date1 is before date2");
} else if (date1 > date2) {
    console.log("date1 is after date2");
} else {
    console.log("date1 is the same as date2");
}

Here, date2 is greater (by being later) than date, so date1 is before date2 is printed.

If you remember that the timestamps of Date objects are defined by milliseconds since the epoch, it will help you remember why being a later date means you are greater than older dates.


Formatting Dates as Strings

In a second, we will go over how to use date-fns to help you format dates, but it is helpful to know the built in ways you can format dates in the Date objects.

You can use toString() to convert it to a readable string:

console.log(now.toString()); // Converts to a readable string

On my machine, this printed Sat Jul 06 2024 18:23:59 GMT-0700 (Pacific Daylight Time)

You can also use toUTCString(), which will convert it to a readable string in the UTC time zone:

console.log(now.toUTCString()); // Converts to a string in UTC time zone

On my machine, this printed Sun, 07 Jul 2024 01:24:50 GMT (I did it around the same time I did the previous one, so you can see how the timezones differ).

You can use toISOString() to convert it to an ISO 8601 string:

console.log(now.toISOString()); // Converts to an ISO 8601 string

Lastly, you can use toLocaleString() to convert to a locale-specific string

console.log(now.toLocaleString()); // Converts to a locale-specific string

Parsing Dates

Lastly, you can parse a Date, which returns the milliseconds since the epoch.

let now = new Date();
let parsedDate = Date.parse(now); // Returns milliseconds since epoch
console.log(parsedDate);

Using date-fns

date-fns is a popular JavaScript library for working with dates. It provides a comprehensive set of functions for manipulating, formatting, and comparing dates in a more straightforward and functional programming style than the native JavaScript Date object. In the rest of this article, we will go over the basics of the package, and the most common uses that I find myself doing with it.

In your project, make sure you run npm install date-fns to install the package.

Formatting Dates

date-fns provides MANY ways to easily format your dates. You can use the format function to easily convert your date, passing the date and the format that you want it in.

First, import format

import { format } from 'date-fns';

Here is the basic usage of the function. You pass it a date, and the format that you want it in as a template string:

const now = new Date();
const formattedDate = format(now, 'yyyy-MM-dd');
console.log(formattedDate); // e.g., 2024-07-06

Visit the following link to see the full list of format strings you can pass to the format

date-fns Documentation

Here are some common ones that I use:

  1. Full Date and Time
const now = new Date();
const formattedDate = format(now, 'yyyy-MM-dd HH:mm:ss');
console.log(formattedDate); // e.g., 2024-07-06 14:30:45
  1. Long Date Format
const now = new Date();
const longFormat = format(now, 'PPPP');
console.log(longFormat); // e.g., "Saturday, July 6th, 2024"
  1. Short Date Format
const now = new Date();
const shortFormat = format(now, 'P');
console.log(shortFormat); // e.g., "07/06/2024"
  1. Custom Formats
const now = new Date();
const formattedDate1 = format(now, 'EEEE, MMMM do, yyyy');
console.log(formattedDate1); // e.g., Saturday, July 6th, 2024

const formattedDate2 = format(now, 'hh:mm a');
console.log(formattedDate2); // e.g., 02:30 PM
  1. Usingformatwith locales

To format dates according to different locales, you can use the format function with the locale option.

First, import the locales

import { format } from 'date-fns';
import { fr } from 'date-fns/locale'; // French locale

Next, you can do something like this to format the date to that locale:

const now = new Date();
const formattedDate = format(now, 'PPP', { locale: fr });
console.log(formattedDate); // e.g., 6 juil. 2024
  1. Relative Formatting ("in 3 days")

You can use formatRelative for relative formatting:

import { formatRelative } from 'date-fns';

const now = new Date();
const futureDate = new Date(now.getTime() + 1000 * 60 * 60 * 24 * 3); // 3 days in the future
const relativeFormat = formatRelative(futureDate, now);
console.log(relativeFormat); // e.g., "in 3 days"
  1. Distance Between Dates ("7 days")
import { formatDistance } from 'date-fns';

const now = new Date();
const pastDate = new Date(now.getTime() - 1000 * 60 * 60 * 24 * 7); // 7 days in the past
const distance = formatDistance(pastDate, now);
console.log(distance); // e.g., "7 days"
  1. Distance to Now ("6 months")
import { formatDistanceToNow } from 'date-fns';

const pastDate = new Date('2024-01-01');
const distanceToNow = formatDistanceToNow(pastDate);
console.log(distanceToNow); // e.g., "6 months"

Adding Days

Import addDays to easily add days to your Date objects.

import { addDays } from 'date-fns';

const now = new Date();
const futureDate = addDays(now, 10);
console.log(futureDate); // 10 days from now

Comparing Days

You can use differenceInDays to easily calculate the difference in days between two dates.

import { differenceInDays } from 'date-fns';

const date1 = new Date('2024-07-06');
const date2 = new Date('2024-07-07');

const diff = differenceInDays(date2, date1);
console.log(diff); // 1

Thanks for Reading!

I hope this article gave you a good basis on how to work with dates in JavaScript, and how to make it even easier with date-fns. Thanks for reading!