Con Swift 3, in base alle tue esigenze, puoi scegliere uno dei due seguenti modi per risolvere il tuo problema.
1. Visualizza la differenza tra due date per l'utente
Puoi usare a DateComponentsFormatter
per creare stringhe per l'interfaccia della tua app. DateComponentsFormatter
ha una maximumUnitCount
proprietà con la seguente dichiarazione:
var maximumUnitCount: Int { get set }
Utilizzare questa proprietà per limitare il numero di unità visualizzate nella stringa risultante. Ad esempio, con questa proprietà impostata su 2, anziché "1h 10m, 30s", la stringa risultante sarebbe "1h 10m". Utilizzare questa proprietà quando si è limitati allo spazio o si desidera arrotondare i valori all'unità grande più vicina.
Impostando maximumUnitCount
il valore su 1
, si garantisce di visualizzare la differenza in una solaDateComponentsFormatter
unità (anni, mesi, giorni, ore o minuti).
Il codice Playground di seguito mostra come visualizzare la differenza tra due date:
import Foundation
let oldDate = Date(timeIntervalSinceReferenceDate: -16200)
let newDate = Date(timeIntervalSinceReferenceDate: 0)
let dateComponentsFormatter = DateComponentsFormatter()
dateComponentsFormatter.allowedUnits = [NSCalendar.Unit.year, .month, .day, .hour, .minute]
dateComponentsFormatter.maximumUnitCount = 1
dateComponentsFormatter.unitsStyle = DateComponentsFormatter.UnitsStyle.full
let timeDifference = dateComponentsFormatter.string(from: oldDate, to: newDate)
print(String(reflecting: timeDifference)) // prints Optional("5 hours")
Si noti che DateComponentsFormatter
arrotonda il risultato. Pertanto, una differenza di 4 ore e 30 minuti verrà visualizzata come 5 ore .
Se devi ripetere questa operazione, puoi refactificare il tuo codice:
import Foundation
struct Formatters {
static let dateComponentsFormatter: DateComponentsFormatter = {
let dateComponentsFormatter = DateComponentsFormatter()
dateComponentsFormatter.allowedUnits = [NSCalendar.Unit.year, .month, .day, .hour, .minute]
dateComponentsFormatter.maximumUnitCount = 1
dateComponentsFormatter.unitsStyle = DateComponentsFormatter.UnitsStyle.full
return dateComponentsFormatter
}()
}
extension Date {
func offset(from: Date) -> String? {
return Formatters.dateComponentsFormatter.string(from: oldDate, to: self)
}
}
let oldDate = Date(timeIntervalSinceReferenceDate: -16200)
let newDate = Date(timeIntervalSinceReferenceDate: 0)
let timeDifference = newDate.offset(from: oldDate)
print(String(reflecting: timeDifference)) // prints Optional("5 hours")
2. Ottieni la differenza tra due date senza formattazione
Se non è necessario visualizzare all'utente la formattazione della differenza tra due date, è possibile utilizzare Calendar
. Calendar
ha un metodo dateComponents(_:from:to:)
che ha la seguente dichiarazione:
func dateComponents(_ components: Set<Calendar.Component>, from start: Date, to end: Date) -> DateComponents
Restituisce la differenza tra due date.
Il codice Playground di seguito che utilizza dateComponents(_:from:to:)
mostra come recuperare la differenza tra due date restituendo la differenza in un solo tipo di Calendar.Component
(anni, mesi, giorni, ore o minuti).
import Foundation
let oldDate = Date(timeIntervalSinceReferenceDate: -16200)
let newDate = Date(timeIntervalSinceReferenceDate: 0)
let descendingOrderedComponents = [Calendar.Component.year, .month, .day, .hour, .minute]
let dateComponents = Calendar.current.dateComponents(Set(descendingOrderedComponents), from: oldDate, to: newDate)
let arrayOfTuples = descendingOrderedComponents.map { ($0, dateComponents.value(for: $0)) }
for (component, value) in arrayOfTuples {
if let value = value, value > 0 {
print(component, value) // prints hour 4
break
}
}
Se devi ripetere questa operazione, puoi refactificare il tuo codice:
import Foundation
extension Date {
func offset(from: Date) -> (Calendar.Component, Int)? {
let descendingOrderedComponents = [Calendar.Component.year, .month, .day, .hour, .minute]
let dateComponents = Calendar.current.dateComponents(Set(descendingOrderedComponents), from: from, to: self)
let arrayOfTuples = descendingOrderedComponents.map { ($0, dateComponents.value(for: $0)) }
for (component, value) in arrayOfTuples {
if let value = value, value > 0 {
return (component, value)
}
}
return nil
}
}
let oldDate = Date(timeIntervalSinceReferenceDate: -16200)
let newDate = Date(timeIntervalSinceReferenceDate: 0)
if let (component, value) = newDate.offset(from: oldDate) {
print(component, value) // prints hour 4
}
NSDateComponentsFormatter
. È molto configurabile e ti consente di ottenere risultati opportunamente concisi (ad es.maximumUnitCount = 1
.).