LoginSignup
11
11

More than 5 years have passed since last update.

現在との時間差を計算する(後追い)

Posted at

Swiftで現在からの経過時間を計算するNSDateのExtension」(@hayakawatomoakiさん) を読んだら面白そうだったので、自分でも書いてみたくなりました。
 まるきり後出しなので、なるべく短く、いかにも簡単そうに書きたいです (希望)。

import Foundation

enum TimeDuration {
    case Day(Int), Hour(Int), Minute(Int), Second(Int)
}

extension NSDate {
    func durationFromNow() -> TimeDuration {
        let value = Int(self.timeIntervalSinceNow)
        let duration = (Minute: 60, Hour: 3600, Day: 3600*24)
        switch abs(value) {
        case 0..<duration.Minute:
            return .Second(value)
        case duration.Minute..<duration.Hour:
            return .Minute(value / duration.Minute)
        case duration.Hour..<duration.Day:
            return .Hour(value / duration.Hour)
        default:
            return .Day(value / duration.Day)
        }
    }
}

 戻り値を文字列ではなく、列挙型にしてみました。測定結果を秒・分・時・日の4タイプに分け、具体的な数字をくっつけて返します。データが単純なので、処理もカンタン。
 素直に文字列を返すほうが使いやすいのですが、このくらい緩いメソッドなら使い回しもできそうです。

 使うときはこのような感じになります。

// 対象時刻を用意 (2015年1月1日)
let day = NSCalendar.currentCalendar().dateWithEra(1, year: 2015, month: 1, day: 1, hour: 0, minute: 0, second: 0, nanosecond: 0)

// 変換用のクロージャ
let s = { (n: Int, s: String) -> String in
    String(abs(n)) + s + (n <= 0 ? "前" : "後")
}

// NSDateを取り出して処理
day.map {
    d -> () in
    var str: String
    switch d.durationFromNow() {
    case .Second(let n):
        str = s(n, "秒")
    case .Minute(let n):
        str = s(n, "分")
    case .Hour(let n):
        str = s(n, "時間")
    case .Day(let n):
        str = s(n, "日")
    }
    println("\(str)のNSDateです") // -> 40日前のNSDateです (ヒエー)
}

 durationFromNow () の戻り値は、列挙型に整数がついてくるだけです。したがって用途に応じて文字列に変える必要があります。ここではクロージャを使っていますが、enumに関数を付けてもよさそうですね。
 なおNSDateはNSCalendarで用意しました。これだけでかなり楽ができます。

11
11
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
11
11