W Swift 3, w zależności od potrzeb, możesz wybrać jeden z dwóch poniższych sposobów rozwiązania problemu.
1. Wyświetl różnicę między dwiema datami dla użytkownika
Możesz użyć a, DateComponentsFormatter
aby utworzyć ciągi interfejsu aplikacji. DateComponentsFormatter
ma maximumUnitCount
właściwość z następującą deklaracją:
var maximumUnitCount: Int { get set }
Użyj tej właściwości, aby ograniczyć liczbę jednostek wyświetlanych w wynikowym ciągu. Na przykład, jeśli ta właściwość jest ustawiona na 2, zamiast „1h 10m, 30s”, wynikowy ciąg miałby wartość „1h 10m”. Tej właściwości należy użyć, gdy jest ograniczona przestrzeń lub chcesz zaokrąglić wartości do najbliższej dużej jednostki.
Ustawiając maximumUnitCount
wartość na 1
, masz gwarancję wyświetlenia różnicy tylko w jednej DateComponentsFormatter
jednostce (lata, miesiące, dni, godziny lub minuty).
Poniższy kod placu zabaw pokazuje, jak wyświetlić różnicę między dwiema datami:
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")
Zauważ, że DateComponentsFormatter
zaokrągla wynik. Dlatego różnica 4 godzin i 30 minut zostanie wyświetlona jako 5 godzin .
Jeśli musisz powtórzyć tę operację, możesz zmienić kod:
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. Uzyskaj różnicę między dwiema datami bez formatowania
Jeśli nie musisz wyświetlać z formatowaniem różnicy między dwiema datami dla użytkownika, możesz użyć Calendar
. Calendar
ma metodę, dateComponents(_:from:to:)
która ma następującą deklarację:
func dateComponents(_ components: Set<Calendar.Component>, from start: Date, to end: Date) -> DateComponents
Zwraca różnicę między dwiema datami.
Poniższy kod placu zabaw, który używa, dateComponents(_:from:to:)
pokazuje, jak odzyskać różnicę między dwiema datami, zwracając różnicę tylko w jednym typie Calendar.Component
(lata, miesiące, dni, godziny lub minuty).
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
}
}
Jeśli musisz powtórzyć tę operację, możesz zmienić kod:
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
. Jest bardzo konfigurowalny, co pozwala uzyskać odpowiednio zwięzłe wyniki (np.maximumUnitCount = 1
.).