栃木県のJavaエンジニア、WEBプログラマーのためのサイト

2014.12.29[Swift] NSDateを拡張する

NSDate

Swift で日付を扱う場合、NSDate を使うことになりますが、これ使うの凄い面倒なんですよね。
例えば、指定日付で作成したい場合は

let components = NSDateComponents()
components.year = 2014
components.month = 12
components.day = 29
components.hour = 0
components.minute = 0
components.second = 0

let date = NSCalendar.currentCalendar().dateFromComponents(components)

と、こんなに書かないといけません。

また、先程作成した NSDate のインスタンス date から、年を取り出そうとすると

let year = NSCalendar.currentCalendar().components(.CalendarUnitYear, fromDate: date!).year

と、とても面倒。
なので、extension 機能を使って拡張してみます。

extension

Swift ではクラスの機能を拡張する方法として継承の他に、既存クラスにそのまま機能を追加出来るエクステンションと呼ばれる機能があります。
継承との大きな違いはプロパティの追加が Computed Property しか出来ないことでしょうか。

では、先程の指定日付で NSDate を生成する機能を、createメソッドとして extension を使って実装してみます。

import Foundation

extension NSDate {
    class func create(#year: Int, month: Int, day: Int, hour: Int = 0, minute: Int = 0, second: Int = 0) -> NSDate? {
        let components = NSDateComponents()
        components.year = year
        components.month = month
        components.day = day
        components.hour = hour
        components.minute = minute
        components.second = second

        return NSCalendar.currentCalendar().dateFromComponents(components)
    }
}

let date = NSDate.create(year: 2015, month: 12, day: 29)

せっかくなので、各日時の要素を Computed Property で取り出せる機能も追加して完成させます。

完成

import Foundation

extension NSDate {
    private var components: NSDateComponents {
        return NSCalendar.currentCalendar().components(.CalendarUnitYear | .CalendarUnitMonth | .CalendarUnitDay | .CalendarUnitWeekday | .CalendarUnitHour | .CalendarUnitMinute | .CalendarUnitSecond, fromDate: self)
    }
    
    var year: Int {
        return components.year
    }

    var month: Int {
        return components.month
    }

    var day: Int {
        return components.day
    }

    var weekday: Int {
        return components.weekday
    }
    
    var hour: Int {
        return components.hour
    }

    var minute: Int {
        return components.minute
    }

    var second: Int {
        return components.second
    }

    class func create(#year: Int, month: Int, day: Int, hour: Int = 0, minute: Int = 0, second: Int = 0) -> NSDate? {
        let components = NSDateComponents()
        components.year = year
        components.month = month
        components.day = day
        components.hour = hour
        components.minute = minute
        components.second = second

        return NSCalendar.currentCalendar().dateFromComponents(components)
    }
}

まとめ

  • extension を使用すると、既存クラスに機能を追加できる。
  • extension では、プロパティの追加が Computed Property のみ。
この記事について
  • スッキリ (0)
  • 普通 (0)
  • 消化不良 (0)