Getting the number of days between two dates in Swift

Swift Date

There are a few variations when dealing with counting days. So, you need to ask yourself the definition of a day beforehand.

What is your definition of a day? #

A day can be interpreted in two ways.

1. Day as time pass midnight
This is the kind of day that we use in our daily life. We consider it another day once the time passes midnight. For example, October 29, 23:59 and October 30, 00:01 consider one day different even it is only two minutes apart.

We don't care about time in this scenario.

2. Day as 24 hours time unit
This is a kind of day in a term of a unit of time. One day is 24 hours. For the same example, October 29, 23:59 and October 30, 00:01 consider two minutes different, not a day different.

In this kind of implementation, we care about time. You can use this when you want to count an elapsed time between two dates. That is the only scenario when I think this kind of counting makes sense.

Do you include a start date? #

This is also an important question to ask before coding. There are scenarios that make sense for both of them.

1. Not include a start date
You usually have a start date in the counting when the number of days between two dates represents a remaining time between today until destination date. For example, if today is October 29 and your payment due date is October 30, people expected the number of days between two dates to be one (due date is tomorrow). So, in this kind of scenario, you don't include the start date in the counting.

2. Including a start date
One scenario that you need to include a start date is when you book a hotel room. If you book a hotel between October 29 and October 30, you would expect something that says two days and one night. You need to include a start date in this case.

After you know all the variation for counting the number of days between dates, you can pick the one that suits you. And the following are how you implement all of them.

Number of days pass midnight, not including a start date #

extension Calendar {
func numberOfDaysBetween(_ from: Date, and to: Date) -> Int {
let fromDate = startOfDay(for: from) // <1>
let toDate = startOfDay(for: to) // <2>
let numberOfDays = dateComponents([.day], from: fromDate, to: toDate) // <3>

return numberOfDays.day!
}
}

<1>, <2> As we mentioned before, counting day as a time pass midnight doesn't consider time components, so we use startOfDay(for:) to convert that date to the beginning of that day (00:00:00).
<3> Then we get a day difference between those two dates.

We create this method as an extension of Calendar because day always needs a time zone and calendar to interpret. We already discussed this in the previous post, Understanding Date and DateComponents. I encourage you to check it out if you haven't read it yet.

The midnight, in this case, will be based on a calendar that calls this function.

Number of days pass midnight, including a start date #

This implementation is the same as the previous one. The only difference is we add one more day to the result.

extension Calendar {
func numberOfDaysBetween(_ from: Date, and to: Date) -> Int {
let fromDate = startOfDay(for: from)
let toDate = startOfDay(for: to)
let numberOfDays = dateComponents([.day], from: fromDate, to: toDate)

return numberOfDays.day! + 1 // <1>
}
}

<1> We add another day to the result.

Number of 24 hours days, not including a start date #

The implementation is similar to our previous example, but we get a day component from dates without stripping out time component.

func numberOfDaysBetween(_ from: Date, and to: Date) -> Int {
let numberOfDays = dateComponents([.day], from: from, to: to)

return numberOfDays.day!
}

Number of 24 hours days, including a start date #

I can't think of any scenario where this implementation makes sense, but I will put it here for completeness.

func numberOf24DaysBetween(_ from: Date, and to: Date) -> Int {
let numberOfDays = dateComponents([.day], from: from, to: to)

return numberOfDays.day! + 1
}

Feel free to follow me on Twitter and ask your questions related to this post. Thanks for reading and see you next time.

If you enjoy my writing, please check out my Patreon https://www.patreon.com/sarunw and become my supporter. Sharing the article is also greatly appreciated.

Become a patron Tweet Share

If you enjoy this article, you can subscribe to the weekly newsletter.

Every Friday, you’ll get a quick recap of all articles and tips posted on this site — entirely for free.

← Home