Swift 3では、ニーズに応じて、次の2つの方法のいずれかを選択して問題を解決できます。
1. 2つの日付の違いをユーザーに表示する
a DateComponentsFormatter
を使用して、アプリのインターフェイスの文字列を作成できます。次の宣言をDateComponentsFormatter
持つmaximumUnitCount
プロパティがあります。
var maximumUnitCount: Int { get set }
このプロパティを使用して、結果の文字列に表示される単位の数を制限します。たとえば、このプロパティを2に設定すると、「1h 10m、30s」の代わりに、結果の文字列は「1h 10m」になります。スペースに制約がある場合、または値を最も近い大きな単位に切り上げる場合は、このプロパティを使用します。
maximumUnitCount
の値をに設定することにより1
、1つDateComponentsFormatter
の単位(年、月、日、時間、または分)のみで差を表示することが保証されます。
以下のPlaygroundコードは、2つの日付の違いを表示する方法を示しています。
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")
DateComponentsFormatter
は結果を切り上げることに注意してください。したがって、4時間と30分の差は5時間と表示されます。ます。
この操作を繰り返す必要がある場合は、コードをリファクタリングできます。
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.フォーマットせずに2つの日付の違いを取得する
2つの日付の差をフォーマットしてユーザーに表示する必要がない場合は、を使用できますCalendar
。次の宣言を持つCalendar
メソッドdateComponents(_:from:to:)
があります。
func dateComponents(_ components: Set<Calendar.Component>, from start: Date, to end: Date) -> DateComponents
2つの日付の差を返します。
以下のPlaygroundコードdateComponents(_:from:to:)
は、1つのタイプCalendar.Component
(年、月、日、時間、または分)のみで差を返すことにより、2つの日付の差を取得する方法を示しています。
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
}
}
この操作を繰り返す必要がある場合は、コードをリファクタリングできます。
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
。それは非常に構成可能であり、適切に簡潔な結果を得ることができます(例:).maximumUnitCount = 1
。