title: countdown from current date to specific date swift
body: <p>Users can sell items and add an expiration date that varies from 1-3 weeks out from current date. </p>
  
  <p>This is how I store the expiration date as a <code>Double</code>. Do I need to be explicit about other date components like year, month, etc?</p>
  
  <pre><code>enum Weeks: Int  {
      case one
      case two
      case three
  }
  
  extension Weeks {
      var timeInterval: Double? {
          let currentDate = Date()
          let calendar = Calendar.current
          let calendarComponents: Set&lt;Calendar.Component&gt; = 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
          }
      }
  }
  </code></pre>
  
  <p>This is how I calculate the countdown in <code>Date</code> extension:</p>
  
  <pre><code>func countdown(to date: Date) -&gt; 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 &lt;= 0 &amp;&amp; hour &lt;= 0 &amp;&amp; minute &lt;= 0 &amp;&amp; second &lt;= 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)
  }
  </code></pre>
  
  <p>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.</p>
  
  <pre><code>let expirationDate = Date(timeIntervalSince1970: self.item.expirationDate)
  
  let response = currentDate.countdown(to: expirationDate)
  </code></pre>
  
  <p>When I create date manually and test like below, it works as expected.</p>
  
  <pre><code>var comp = calendar.dateComponents(calendarComponents, from: Date())
  
  comp.year = 2017
  comp.month = 8
  comp.day = 24
  comp.minute = 50
  comp.second = 30
  </code></pre>
  
  <p>What am I doing wrong? Am I persisting date as time interval incorrectly, or creating date from timeInterval incorrectly?</p>
  
  <p>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.</p>