Adding (or subtracting) date and time

Hey ,

I'm thrilled to help you learn JavaScript. Unfortunately, you've landed on a page where you cannot access with your current purchase.

Please upgrade (use this link) access this content.

I'm super eager to help you learn more!

Adding (or subtracting) date and time

Date setter methods are often used to add or subtract date and time. If you do a quick google for “how to add a date in JavaScript”, you’ll see lots of Stack Overflow posts showing this answer:

const date = new Date(2019, 1, 25)
const threeDaysLater = date.setDate(date.getDate() + 3)

console.log(threeDaysLater) // 28 February 2019

Let’s break down why this works (and what’s bad about this answer).

How to use setDate to add days

setDate sets the date to a specific value. In the example above, we want to add 3 days to 25 Feb. This means we want to set date to 28.

const date = new Date(2019, 1, 25)
const threeDaysLater = date.setDate(28)

console.log(threeDaysLater) // 28 February 2019

Now, if we want +3 days to work regardless of the start date, we can’t use the number 28. That’s hardcoding. It doesn’t work.

To make +3 days work, we need to know the current date, then we add 3 to it.

const currentDate = date.getDate()
const daysToAdd = 3
const newDate = currentDate + 3

// Setting the new date
const threeDaysLater = date.setDate(newDate)

If we combine the three steps above, we get this:

const threeDaysLater = date.setDate(date.getDate() + 3)

What’s bad about the setDate method

setDate mutates the original date.

const date = new Date(2019, 1, 25)
const threeDaysLater = date.setDate(date.getDate() + 3)

console.log(date) // 28 February 2019
console.log(threeDaysLater) // 28 February 2019

You shouldn’t mutate objects. You already learned that in the Best Practices Module. (Revisit the lesson if you need a refresher).

This doesn’t mean you can’t use setDate (and other setter methods). It means you shouldn’t use them carelessly.

The right way to use setDate

If you want to use setDate, make sure you’re don’t mutate the original date. To do so, you can create a temporary date:

const date = new Date(2019, 1, 25)
const tempDate = new Date(date)
const threeDaysLater = tempDate.setDate(tempDate.getDate() + 3)

console.log(date) // 25 February 2019
console.log(threeDaysLater) // 28 February 2019

Alternative methods to add/subtract dates

You can use two other methods to add/subtract date and time. They are:

  1. Create a new date with timestamp
  2. Create a new date with arguments

Both methods do not mutate the original date. They’re also easier to read and understand. Of the two, I prefer the second method.

Method 1: Create a new date with timestamp

You’ll do this:

  1. Get the current timestamp with getTime
  2. Add (or subtract) the timestamp to get a new timestamp
  3. Create a new date with the new timestamp

If you use timestamp, you need to be familiar with timestamp math. Here are the values you’ll need to know:

  1. One second: 1000 milliseconds (1000, in timestamp value)
  2. One minute: 60 seconds (60 x 1000 = 60000 in timestamp value)
  3. One hour: 60 minutes (60 x 60 x 1000 = 3600000 in timestamp value)
  4. One day: 24 hours (24 x 60 x 60 x 1000 = 86400000 in timestamp value)

Here’s the code to add three days:

const date = new Date(2019, 1, 25)
const timestampForOneDay = 86400000
const threeDaysLater = new Date(date.getTime() + timestampForOneDay * 3)

console.log(threeDaysLater) // 28 February 2019

This method does not mutate the original date object

console.log(date) // 25 February 2019

Method 2: Create a new date with arguments

What I mean by using arguments is to create a new Date object with the year, month, day, hours, minute, seconds and milliseconds values. (You can omit any values you don’t need).

Here’s an example to add three days to the original date.

const date = new Date(2019, 1, 25)
const year = date.getFullYear()
const month = date.getMonth()
const day = date.getDate()

const threeDaysLater = new Date(year, month, day + 3)

console.log(threeDaysLater) // 28 February 2019

Notice how this method feels familiar to you already? It feels familiar because you’ve already created dates with the arguments method for a while. This method is much easier to grasp.

Likewise, this method does not mutate the original date object

console.log(date) // 25 February 2019

Calculating Overflow values

Let’s say you want to add three days to 28 February. What day would this be? Should it be 2 March (when there’s a leap year) or 3 March (when there’s no leap year)?

In JavaScript, you don’t have to worry about these calculations. If the number you provide to the Date constructor is larger than normally acceptable values, JavaScript will calculate the correct date for you automatically.

const date = new Date(2019, 1, 28) // 28 Feb 2019
const year = date.getFullYear()
const month = date.getMonth()
const day = date.getDate()

// 28 + 3 === 31.
// JavaScript converts 31 Feb 2019 -> 3 March 2019 automatically
const threeDaysLater = new Date(year, month, day + 3)

console.log(threeDaysLater) // 3 March 2019

The reverse is true.

const date = new Date(2019, 2, 3) // 3 March 2019
const year = date.getFullYear()
const month = date.getMonth()
const day = date.getDate()

// 3 - 3 === 0.
// JavaScript converts 0 March 2019 -> 28 February 2019 automatically
const threeDaysEarlier = new Date(year, month, day - 3)

console.log(threeDaysEarlier) // 28 February 2019

This applies to setter methods too.

const date = new Date(2019, 1, 28)
const tempDate = new Date(date)
const threeDaysLater = tempDate.setDate(tempDate.getDate() + 3)

console.log(date) // 28 February 2019
console.log(threeDaysLater) // 3 March 2019

Exercise

  1. Add 20 days to 28 June 2019 with the timestamp method
  2. Subtract 30 days from 28 June 2019 with the timestamp method
  3. Add 20 days to 28 June 2019 by creating a new date with arguments
  4. Subtract 30 days from 28 June 2019 by creating a new date with arguments
  5. Add 20 days to 28 June 2019 with setDate
  6. Subtract 30 days from 28 June 2019 with setDate