Yonahg
Yonahg

Reputation: 23

Calculating the number of days between two dates in swift

Why does the result of using the variable today rather than Date() when calculating the number of days between two dates make a difference in swift?

var numDays: Int
var today = Date()
var twoWeeksFromNow: Date = Calendar.current.date(byAdding: .day, 
value: 14, to: Date())!

var numDaysWithDate: Int = 
Calendar.current.dateComponents([.day], from: Date(), to: 
twoWeeksFromNow).day!
var numDaysWithToday: Int = 
Calendar.current.dateComponents([.day], from: today, to: 
twoWeeksFromNow).day!

print(numDaysWithDate) // 13
print(numDaysWithToday) // 14

Upvotes: 1

Views: 300

Answers (2)

Duncan C
Duncan C

Reputation: 131408

The key thing to understand can be boiled down to this. The following code:

var today = Date()
print("Woof")
print(Date().timeIntervalSinceReferenceDate - today.timeIntervalSinceReferenceDate )

Logs a value larger than 0. On my machine, it displays a value of 0.00047898292541503906.

That's because the value of the second Date() is captured after today is captured. By adding a print statement, slows the code enough so that the two values are over 4 milliseconds apart. By removing the print statement the two Date() values are less than 2 milliseconds apart.

If you do a series of Calendar/Date calculations and take a new value of Date() each time, the new Date will be a tiny fraction of a second later than the "today" value you capture at the beginning of your code. The difference is enough to throw off your number of days calculations, as @jnpdx explained in their excellent answer. (voted)

Upvotes: 1

jnpdx
jnpdx

Reputation: 52347

It has to do with the order that you're creating your variables and comparing them.

The first thing you do is create today. Then, you create twoWeeksFromNow, based on a new Date() that will be slightly further in the future than today was. On my machine, in a playground, the second date is about 300 microseconds further in the future than the first.

Then, for numDaysWithDate, you compare twoWeeksFromNow to another new Date(), even more slightly in the future. So, your time frame is very slightly less than 2 full weeks, giving you 13 days.

But, for numDaysWithToday, you compare twoWeeksFromNow with the original today, which was created before twoWeeksFromNow was, making it slightly longer than 2 weeks, giving you 14 days.

If you change the order of the the today and twoWeeksFromNow declarations, you can see a different result:

var twoWeeksFromNow: Date = Calendar.current.date(byAdding: .day,
value: 14, to: Date())!
var today = Date()

Now, because today was created slightly later than the date that twoWeeksFromNow was created from, both results are 13.

Upvotes: 2

Related Questions