[iOS] NSDateをもうちょっと簡単に扱いたいなーとSwiftでユーティリティクラス作ってみた

2016/02/1

こんにちは。きんくまです。

NSDateって、NSDateComponentsとかNSCalendarとかを使って変換するので面倒だったりします。
もうちょっと簡単に扱いたいなーと、以前Objective-Cで作っていたものがありまして。
今回Swiftに書き直してみました。で、githubにpushしてみました。

>> KinkumaDesign/SwiftNSDateUtilityExtension – Swift
 

はじめる前に

したのサンプルコードで出力されるのは、iPhoneシミュレーターの言語設定が英語のときのものであります。
端末の言語設定やロケールなどが変わると出力結果も変わります。

インストール

“utils/NSDate+DateUtil.swift”をコピーします。1ファイルだけなんで。

特定の日を作りたい

時/分/秒はオプションです

let date:NSDate = NSDate.dateWithYear(2016, month: 2, day: 1)
print("date = \(date.yearMonthDayString)") //February 01, 2016

let date2:NSDate = NSDate.dateWithYear(2016, month: 2, day: 3, hour: 18, minute: 30, second: 25)
let date2Str:String = date2.stringWithDateFormatString("yyyy/MM/dd HH:mm:ss")
print("date2 = \(date2Str)") //2016/02/03 18:30:25

その月の最初の日は何曜日か

let date:NSDate = NSDate.dateWithYear(2016, month: 2, day: 18)
print("first week day in Feb. 2016 = \(date.firstWeekdayInMonth)")
//first week day in Feb. 2016 = 2(月曜)

//日曜 = 1, 月曜 = 2, というふうに続きます

その月は何日あるか

let date:NSDate = NSDate.dateWithYear(2016, month: 2, day: 18)
print("number of days in Feb. 2016 = \(date.numberOfDaysInMonth)") //29

その月は何週あるか

let date:NSDate = NSDate.dateWithYear(2016, month: 2, day: 18)
print("number of week in Feb. 2016 = \(date.numberOfWeekInMonth)") //5

日付の構成要素(年/月/日 曜日 時:分:秒)に分解

let date:NSDate = NSDate.dateWithYear(2016, month: 2, day: 3, hour: 15, minute: 30, second: 25)
print("year: \(date.year)")
print("month: \(date.month)")
print("day: \(date.day)")
print("weekday: \(date.weekday)")
print("hour \(date.hour)")
print("minute \(date.minute)")
print("second \(date.second)")
print("nanosecond \(date.nanoSecond)")

前の日、次の日がほしい

let date:NSDate = NSDate.dateWithYear(2016, month: 2, day: 1)
let nextDate:NSDate = date.nextDate
let previousDate:NSDate = date.previousDate

print("next date: \(nextDate.yearMonthDayString)") //February 02, 2016
print("previous date: \(previousDate.yearMonthDayString)") //January 31, 2016

何日の差なのか計算したい

let startDate:NSDate = NSDate.dateWithYear(2016, month: 2, day: 1)
let endDate:NSDate = NSDate.dateWithYear(2016, month: 2, day: 4)
let days:Int = startDate.daysToDate(endDate)

print("\(endDate.stringWithDateFormatString("yyyy/MM/dd")) - \(startDate.stringWithDateFormatString("yyyy/MM/dd")) = \(days)")
//2016/02/04 - 2016/02/01 = 3

文字列にしたい

let date:NSDate = NSDate.dateWithYear(2016, month: 2, day: 3, hour: 15, minute: 32, second: 24)
print("\(date.yearMonthString)") //February 2016
print("\(date.yearMonthDayString)") //February 03, 2016
print("\(date.yearMonthDayWeekdayString)") //Wed, February 03, 2016
print("\(date.yearMonthDayStringShortStyle)") // 2/3/16
print("\(date.yearMonthDayStringMediumStyle)") //Feb 3, 2016

print("\(date.stringWithDateFormatterStyle(NSDateFormatterStyle.FullStyle))") //Wednesday, February 3, 2016
print("\(date.stringWithDateFormatString("yyyy/MM/dd HH:mm:ss"))") //2016/02/03 15:32:24

DateComponentsを作って日付に足し算引き算したい

let date1:NSDate = NSDate.dateWithYear(2016, month: 2, day: 1)
let comp1:NSDateComponents = NSDateComponents()
comp1.day = 5 //5日分足す
let date2:NSDate = date1.dateByAddingComponents(comp1)

print("date2 \(date2.yearMonthDayString)") //February 06, 2016

ライセンス

MITライセンス

NSDate+DateUtil.swift

こっちにも本体のコードを書いておきます。

//
//  NSDate+DateUtil.swift
//
//  Created by Maeda Tasuku on 1/30/16.
//  Copyright © 2016 Kinkuma Design. All rights reserved.
//

import Foundation

extension NSDate {
    private static var _grecorianCalender:NSCalendar!
    
    class func dateWithYear(year:Int, month:Int, day:Int, hour:Int = 0, minute:Int = 0, second:Int = 0)-> NSDate {
        let date:NSDate = NSDate()
        let comps:NSDateComponents = date.gregorianCalendar.components(
            [.Year, .Month, .Day, .Hour, .Minute, .Second, .Nanosecond], fromDate: date)
        comps.year = year
        comps.month = month
        comps.day = day
        comps.hour = hour
        comps.minute = minute
        comps.second = second
        comps.nanosecond = 0
        return date.gregorianCalendar.dateFromComponents(comps)!
    }
    
    var gregorianCalendar:NSCalendar {
        if NSDate._grecorianCalender == nil {
            let cal:NSCalendar = NSCalendar(calendarIdentifier: NSCalendarIdentifierGregorian)!
            cal.timeZone = NSTimeZone.localTimeZone()
            NSDate._grecorianCalender = cal
        }
        return NSDate._grecorianCalender
    }
    
    var currentDateFormatter:NSDateFormatter {
        let formatter:NSDateFormatter = NSDateFormatter()
        formatter.locale = NSLocale.currentLocale()
        formatter.timeZone = NSTimeZone.localTimeZone()
        formatter.dateStyle = NSDateFormatterStyle.NoStyle
        formatter.timeStyle = NSDateFormatterStyle.NoStyle
        return formatter
    }
    
    /**
     * Sunday = 1, Monday = 2, ....
     */
    var firstWeekdayInMonth:Int {
        let cal:NSCalendar = self.gregorianCalendar
        let unitFlags: NSCalendarUnit = [.Year, .Month, .Day]
        let comps:NSDateComponents = cal.components(unitFlags, fromDate: self)
        comps.day = 1
        let firstDay:NSDate = cal.dateFromComponents(comps)!
        return cal.components(NSCalendarUnit.Weekday, fromDate: firstDay).weekday
    }
    
    var weekday:Int {
        return self.gregorianCalendar
            .components(NSCalendarUnit.Weekday, fromDate: self).weekday
    }
    
    var numberOfDaysInMonth:Int {
        return self.gregorianCalendar.rangeOfUnit(NSCalendarUnit.Day,
                                                  inUnit: NSCalendarUnit.Month,
                                                  forDate: self).length
    }
    
    var numberOfWeekInMonth:Int {
        return self.gregorianCalendar.rangeOfUnit(NSCalendarUnit.WeekOfMonth,
                                                  inUnit: NSCalendarUnit.Month,
                                                  forDate: self).length
    }
    
    func daysToDate(endDate:NSDate)-> Int {
        let units:NSCalendarUnit = [.Era, .Year, .Month, .Day]
        let cal:NSCalendar = self.gregorianCalendar
        let comps1:NSDateComponents = cal.components(units, fromDate: self)
        let comps2:NSDateComponents = cal.components(units, fromDate: endDate)
        comps1.hour = 12
        comps2.hour = 12
        let date1:NSDate = cal.dateFromComponents(comps1)!
        let date2:NSDate = cal.dateFromComponents(comps2)!
        return cal.components(NSCalendarUnit.Day, fromDate: date1, toDate: date2,
            options: NSCalendarOptions(rawValue: 0)).day
    }
    
    var yearMonthDayComponents:NSDateComponents {
        return self.gregorianCalendar.components([.Year, .Month, .Day], fromDate: self)
    }
    
    var yearMonthComponents:NSDateComponents {
        return self.gregorianCalendar.components([.Year, .Month], fromDate: self)
    }
    
    var weekdayComponents:NSDateComponents {
        return self.gregorianCalendar.components([.Weekday], fromDate: self)
    }
    
    var hourMinuteSecondComponents:NSDateComponents {
        return self.gregorianCalendar.components([.Hour, .Minute, .Second], fromDate: self)
    }
    
    var year:Int {
        return self.yearMonthComponents.year
    }
    
    var month:Int {
        return self.yearMonthComponents.month
    }
    
    var day:Int {
        return self.yearMonthDayComponents.day
    }
    
    var hour:Int {
        return self.hourMinuteSecondComponents.hour
    }
    
    var minute:Int {
        return self.hourMinuteSecondComponents.minute
    }
    
    var second:Int {
        return self.hourMinuteSecondComponents.second
    }
    
    var nanoSecond:Int{
        return self.gregorianCalendar.component(NSCalendarUnit.Nanosecond, fromDate: self)
    }
    
    var nextDate:NSDate {
        let comps:NSDateComponents = self.yearMonthDayComponents
        comps.day = comps.day + 1
        return self.gregorianCalendar.dateFromComponents(comps)!
    }
    
    var previousDate:NSDate {
        let comps:NSDateComponents = self.yearMonthDayComponents
        comps.day = comps.day - 1
        return self.gregorianCalendar.dateFromComponents(comps)!
    }
    
    var dayString:String {
        let formatter:NSDateFormatter = self.currentDateFormatter
        formatter.dateFormat = "d"
        return formatter.stringFromDate(self)
    }
    
    var yearMonthString:String {
        let formatString:String = NSDateFormatter.dateFormatFromTemplate(
            "yyyyMMMM", options: 0, locale: NSLocale.currentLocale())!
        let formatter:NSDateFormatter = self.currentDateFormatter
        formatter.dateFormat = formatString
        return formatter.stringFromDate(self)
    }
    
    var yearMonthDayString:String {
        let formatString:String = NSDateFormatter.dateFormatFromTemplate(
            "yyyyMMMMdd", options: 0, locale: NSLocale.currentLocale())!
        let formatter:NSDateFormatter = self.currentDateFormatter
        formatter.dateFormat = formatString
        return formatter.stringFromDate(self)
    }
    
    var yearMonthDayWeekdayString:String {
        let formatString:String = NSDateFormatter.dateFormatFromTemplate(
            "yyyyMMMMddEE", options: 0, locale: NSLocale.currentLocale())!
        let formatter:NSDateFormatter = self.currentDateFormatter
        formatter.dateFormat = formatString
        return formatter.stringFromDate(self)
    }
    
    var yearMonthDayStringShortStyle:String {
        let formatter:NSDateFormatter = self.currentDateFormatter
        formatter.dateStyle = NSDateFormatterStyle.ShortStyle
        let yearMonthDate:NSDate = self.gregorianCalendar.dateFromComponents(self.yearMonthDayComponents)!
        return formatter.stringFromDate(yearMonthDate)
    }
    
    var yearMonthDayStringMediumStyle:String {
        let formatter:NSDateFormatter = self.currentDateFormatter
        formatter.dateStyle = NSDateFormatterStyle.MediumStyle
        let yearMonthDate:NSDate = self.gregorianCalendar.dateFromComponents(self.yearMonthDayComponents)!
        return formatter.stringFromDate(yearMonthDate)
    }
    
    func stringWithDateFormatterStyle(style:NSDateFormatterStyle)-> String {
        let formatter:NSDateFormatter = self.currentDateFormatter
        formatter.dateStyle = style
        return formatter.stringFromDate(self)
    }
    
    func stringWithDateFormatString(formatString:String)-> String {
        let formatter:NSDateFormatter = self.currentDateFormatter
        formatter.dateFormat = formatString
        return formatter.stringFromDate(self)
    }
    
    func dateByAddingComponents(offsetComponents:NSDateComponents)-> NSDate {
        return self.gregorianCalendar.dateByAddingComponents(offsetComponents,
            toDate: self, options: NSCalendarOptions(rawValue: 0))!
    }
}
LINEで送る
Pocket

自作iPhoneアプリ 好評発売中!
フォルメモ - シンプルなフォルダつきメモ帳
ジッピー電卓 - 消費税や割引もサクサク計算!

LINEスタンプ作りました!
毎日使える。とぼけたウサギ。LINEスタンプ販売中! 毎日使える。とぼけたウサギ

ページトップへ戻る