NSDate同士の比較は結構面倒な記述になる。
let a = NSDate(), b = NSDate()
a.compare(b) == .OrderedAscending
しかもこれを見て、a < bなのかa > bなのか分かりづらい。
比較演算子を利用できるようにするとこれらの問題が解決する。
演算子のみの実装
public func <(a: NSDate, b: NSDate) -> Bool {
return a.compare(b) == .OrderedAscending
}
public func ==(a: NSDate, b: NSDate) -> Bool {
return a.compare(b) == .OrderedSame
}
public func >(a: NSDate, b: NSDate) -> Bool {
return a.compare(b) == .OrderedDescending
}
public func <=(a: NSDate, b: NSDate) -> Bool {
return a < b || a == b
}
public func >=(a: NSDate, b: NSDate) -> Bool {
return a > b || a == b
}
これらを定義すると比較演算子が利用できるようになるので、直感的に記述することができる。
let currentDate: NSDate
let objectDate: NSDate
// before
if currentDate.compare(objectDate) == .OrderedAscending {
print("alert object")
}
// after
if objectDate < currentDate {
print("alert object")
}
Comparableに準拠させた実装
es_kumagaiさんのコメントを踏まえて。
Comparable
プロトコルに準拠することで、演算子の定義を<
と==
のみで終わらせることができる。
extension NSDate: Comparable {}
public func <(a: NSDate, b: NSDate) -> Bool {
return a.compare(b) == .OrderedAscending
}
public func ==(a: NSDate, b: NSDate) -> Bool {
return a.compare(b) == .OrderedSame
}
この実装にすると更に良いことについては、コメントより抜粋。
こうしたときに面白いのが、他の Equatable を想定した機能を NSDate でも使えるようになるところです。
例えば Swift の配列 Array は、Element が比較可能なときに indexOf(_:) メソッドが使えるようになるのですけど、上のように NSDate を Comparable にしておくと、Array のときにもこれが使えるようになります。