Ghost108 Ghost108 - 1 year ago 61
Swift Question

actual date plus 14 days

i working with swift 3 for osx.
i have this calendar:

enter image description here

this calendar should show the actual date plus 14 days.
Generally it is correct, because 30 - 16 = 14 days between.

this is my code for this:

datePicker.dateValue = Calendar.current.date(byAdding: .day, value: 14, to: Date())!


but at the bottom of my calendar should be visible the days between now and the selected date. but here will be shown 13 days.

why 13 and not 14?

this text label will calculate like this:

txtDiffDays.stringValue = "(\(Calendar.current.dateComponents([.day], from: Date(), to: datePicker.dateValue).day!) Tage)"


where is my mistake?

Answer Source

Here are some experiments that I did in the playground:

enter image description here

let now = Date()
let date = Calendar.current.date(byAdding: .day, value: 14, to: Date())!
let nowDay = Calendar.current.dateComponents([.day], from: Date()).day
let dateDay = Calendar.current.dateComponents([.day], from: date).day
date.timeIntervalSince1970 - Date().timeIntervalSince1970
date.timeIntervalSince1970 - now.timeIntervalSince1970
let days = Calendar.current.dateComponents([.day], from: Date().addingTimeInterval(-1), to: date).day!
let days2 = Calendar.current.dateComponents([.day], from: now, to: date).day!

Base on the result, I think what happens is that some time has passed between "setting the date picker's value" and "calculating the date difference". During both of these actions you did Date(). Since some time has passed, the date that he second Date() creates is a tiny little bit later than the one created by the first Date() call, as you can see from line 8 and 9 in the playground.

Since the second date is a little later, that makes the date difference a little less than 14 whole days, so dateComponents method rounds it down and you get 13.

To fix this, avoid doing two Date() calls. You can just create a local variable called now and use it throughout the method.

let now = Date()

Alternatively, you can use Date().addingTimeInterval(-1) like I did in playground line 10, but I feel like this is a cheat more than a solution.

Recommended from our users: Dynamic Network Monitoring from WhatsUp Gold from IPSwitch. Free Download