Users can sell items and add an expiration date that varies from 1-3 weeks out from current date.
This is how I store the expiration date as a Double. Do I need to be explicit about other date components like year, month, etc?
enum Weeks: Int  {
    case one
    case two
    case three
}
extension Weeks {
    var timeInterval: Double? {
        let currentDate = Date()
        let calendar = Calendar.current
        let calendarComponents: Set<Calendar.Component> = Set(arrayLiteral: Calendar.Component.year, Calendar.Component.month, Calendar.Component.day, Calendar.Component.hour, Calendar.Component.minute, Calendar.Component.second)
        var components = calendar.dateComponents(calendarComponents, from: currentDate)
        switch self {
        case .one: components.weekOfMonth = 1
        case .two: components.weekOfMonth = 2
        case .three: components.weekOfMonth = 3
        }
        if let expirationDate = calendar.date(from: components) {
            return expirationDate.timeIntervalSince1970 as Double
        } else {
            return nil
        }
    }
}
This is how I calculate the countdown in Date extension:
func countdown(to date: Date) -> CountdownResponse {
    let difference = Calendar.current.dateComponents([.day, .hour, .minute, .second], from: self, to: date)
    guard let day = difference.day, let hour = difference.hour, let minute = difference.minute, let second = difference.second else {
        return .error(message: "One or more date components are nil.")
    }
    if day <= 0 && hour <= 0 && minute <= 0 && second <= 0 {
        return .isFinished
    }
    let days = displayableText(from: difference.day)
    let hours = displayableText(from: difference.hour)
    let minutes = displayableText(from: difference.minute)
    let seconds = displayableText(from: difference.second)
    let timeRemaining = "\(days) : \(hours) : \(minutes) : \(seconds)"
    return .result(time: timeRemaining)
}
This is how I'd like to get the countdown, and then I check the response enum for error, or result. But this gives me incorrect time.
let expirationDate = Date(timeIntervalSince1970: self.item.expirationDate)
let response = currentDate.countdown(to: expirationDate)
When I create date manually and test like below, it works as expected.
var comp = calendar.dateComponents(calendarComponents, from: Date())
comp.year = 2017
comp.month = 8
comp.day = 24
comp.minute = 50
comp.second = 30
What am I doing wrong? Am I persisting date as time interval incorrectly, or creating date from timeInterval incorrectly?
As I look over the code I realize that I may be calculating the week wrong. If it's the second week of the month and a user chooses for item to expire in 3 weeks, week of month shouldn't be 3, it needs to be 3 weeks from current week of month. Any guidance on how to fix this logic is appreciated.