Home > OS >  Count Days between Dates Swift (Considering what may be tomorrow.)
Count Days between Dates Swift (Considering what may be tomorrow.)

Time:05-05

I have this code:

extension Date {
    /// From today to self
    /// - Returns: number of days.
    func getDaysUntil() -> Int? {        
        return Calendar.current.dateComponents([.day], from: Date(), to: self).day
    }
}

I need everything to be considered in terms of EST. So regardless of which time zone we are in, everything should be regarded as EST.

I am having a problem when comparing today with tomorrow.

So take the following case:

Date() // (now):: June 15. self (compare to):: June 16.

Regardless the time of day today, I want to say that it's 1 day until the comparison date (self).

So, if it's 11:59pm and the comparison date (self) is 12:01am, I want the result to be 1 day. If it's 12:01am and the comparison date (self) is 11:59pm, I still want the comparison result to be 1.

As it is, no matter what I do, when we get to those extreme edges, the date calculation is off by 1, one way or the other.

Also, this isn't just a today vs. tomorrow issue. The correct count should be the result (considering the today/tomorrow conundrum) for any date.

Is there some fancy trick, or does anyone have any suggestion how we could accomplish this? Thanks!

CodePudding user response:

If you need a default "don't care" time calendrical calculation what you need is to use noon time. Check WWDC session 227 Solutions to Common Date and Time Challenges. Check the "Midnight" part and what is said about why people should NOT use midnight.

extension Calendar {
    static let iso8601 = Calendar(identifier: .iso8601)
}

extension Date {
    /// From today's noon to self's noon
    /// - Returns: number of days.
    var daysFromToday: Int {
        Calendar.iso8601.dateComponents([.day], from: Date().noon, to: noon).day!
    }
    /// Noon time
    /// - Returns: same date at noon
    var noon: Date {
        Calendar.iso8601.date(bySettingHour: 12, minute: 0, second: 0, of: self)!
    }
}

Usage:

let yesterday = DateComponents(calendar: .iso8601, year: 2022, month: 5, day: 2, hour: 23, minute: 59, second: 59).date!

yesterday.daysFromToday  // -1
  • Related