Avec Swift 3, selon vos besoins, vous pouvez choisir l'une des deux façons suivantes pour résoudre votre problème.
1. Afficher la différence entre deux dates à l'utilisateur
Vous pouvez utiliser un DateComponentsFormatter
pour créer des chaînes pour l'interface de votre application. DateComponentsFormatter
a une maximumUnitCount
propriété avec la déclaration suivante:
var maximumUnitCount: Int { get set }
Utilisez cette propriété pour limiter le nombre d'unités affichées dans la chaîne résultante. Par exemple, avec cette propriété définie sur 2, au lieu de "1h 10m, 30s", la chaîne résultante serait "1h 10m". Utilisez cette propriété lorsque vous manquez d'espace ou souhaitez arrondir les valeurs à la grande unité la plus proche.
En définissant maximumUnitCount
la valeur de sur 1
, vous êtes assuré d'afficher la différence dans un seulDateComponentsFormatter
unité (années, mois, jours, heures ou minutes).
Le code Playground ci-dessous montre comment afficher la différence entre deux dates:
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")
Notez que DateComponentsFormatter
arrondit le résultat. Par conséquent, une différence de 4 heures et 30 minutes sera affichée comme 5 heures .
Si vous devez répéter cette opération, vous pouvez refactoriser votre code:
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. Obtenez la différence entre deux dates sans formatage
Si vous n'avez pas besoin d'afficher avec mise en forme la différence entre deux dates pour l'utilisateur, vous pouvez l'utiliser Calendar
. Calendar
a une méthode dateComponents(_:from:to:)
qui a la déclaration suivante:
func dateComponents(_ components: Set<Calendar.Component>, from start: Date, to end: Date) -> DateComponents
Renvoie la différence entre deux dates.
Le code Playground ci-dessous qui utilise dateComponents(_:from:to:)
montre comment récupérer la différence entre deux dates en renvoyant la différence dans un seul type de Calendar.Component
(années, mois, jours, heures ou minutes).
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
}
}
Si vous devez répéter cette opération, vous pouvez refactoriser votre code:
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
. Il est très configurable, vous permettant d'obtenir des résultats concis de manière appropriée (par exemple.maximumUnitCount = 1
).