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:
- Create a new date with timestamp
- 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:
- Get the current timestamp with
getTime
- Add (or subtract) the timestamp to get a new timestamp
- 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:
- One second: 1000 milliseconds (
1000
, in timestamp value)
- One minute: 60 seconds (
60 x 1000 = 60000
in timestamp value)
- One hour: 60 minutes (
60 x 60 x 1000 = 3600000
in timestamp value)
- 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
- Add 20 days to
28 June 2019
with the timestamp method
- Subtract 30 days from
28 June 2019
with the timestamp method
- Add 20 days to
28 June 2019
by creating a new date with arguments
- Subtract 30 days from
28 June 2019
by creating a new date with arguments
- Add 20 days to
28 June 2019
with setDate
- Subtract 30 days from
28 June 2019
with setDate