日付関連クラスのまとめ(Swift3)

#はじめに
日付を扱うクラスを、すぐ忘れるのでまとめました。
同じようなことができるクラスやメソッドがたくさんあります。

|クラス名|説明|サポートOS|
|---|---|---|
|Date |日付と時間を管理するクラスです。 | iOS2.0〜 |
|DateFormatter|日付を適切な書式で表示したいときに利用するクラスです。 | iOS2.0〜 |
|Calendar |カレンダーの情報を提供するクラスです。 | iOS2.0〜 |
|DateComponents|年月日時分秒を個別に管理するクラスです。 |iOS2.0〜 |
|DateInterval|2つの日時の間隔を扱いたいときに利用するクラスです。 | iOS10.0〜 |

# DateFormatter
## ①変換
### 1)文字列 → 日付へ変換

```swift:
    let dateFormater = DateFormatter()
    dateFormater.locale = Locale(identifier: "ja_JP")
    dateFormater.dateFormat = "yyyy/MM/dd HH:mm:ss"
    let date = dateFormater.date(from: "2016/10/3 12:12:12") 
    print(date.description ?? "nilですよ")    // 2016-10-03 03:12:12 +0000    
```

#### 【補足】24時間表示オフ対策
端末の設定 > 一般 > 日付と時刻から24時間表示をオフした場合に、dateがnilになります。

対策として、ロケールを指定します。
例） ja_JP、en_US_POSIX

### 2)日付 → 文字列へ変換

```swift
    let dateFormater = DateFormatter()
    dateFormater.locale = Locale(identifier: "ja_JP")
    dateFormater.dateFormat = "yyyy/MM/dd HH:mm:ss"
    let date = dateFormater.string(from: Date())
    print(date)     // 2017/04/04 10:44:31
```
### 3) DateStyleによる表示の違い

```swift
    let dateFormater = DateFormatter()
    dateFormater.locale = Locale(identifier: "ja_JP")

    //dateStyle : fullの場合
    dateFormater.dateStyle = .full
    print(dateFormater.string(from: Date()))    // 2017年4月4日火曜日
        
    //dateStyle : longの場合
    dateFormater.dateStyle = .long
    print(dateFormater.string(from: Date()))    // 2017年4月4日
        
    //dateStyle : midiumの場合
    dateFormater.dateStyle = .medium
    print(dateFormater.string(from: Date()))    // 2017/04/04
        
    //dateStyle : shortの場合
    dateFormater.dateStyle = .short
    print(dateFormater.string(from: Date()))    // 2017/04/04
```
### 4)TimeStyleによる表示の違い

```swift:
    let dateFormater = DateFormatter()
    dateFormater.locale = Locale(identifier: "ja_JP")


    //timeStyle : fullの場合
    dateFormater.timeStyle = .full
    print(dateFormater.string(from: Date()))    // 2017/04/04 10時44分31秒 日本標準時
        
    //timeStyle : longの場合
    dateFormater.timeStyle = .long
    print(dateFormater.string(from: Date()))    // 2017/04/04 10:44:31 JST
        
    //timeStyle : mediumの場合
    dateFormater.timeStyle = .medium
    print(dateFormater.string(from: Date()))    // 2017/04/04 10:44:31
        
    //timeStyle : shortの場合
    dateFormater.timeStyle = .short
    print(dateFormater.string(from: Date()))    // 2017/04/04 10:44
```

# Calendar
## ①初期設定

### 1)タイムゾーンを指定する

```swift:
    var calendar = Calendar.current
    calendar.timeZone = TimeZone(identifier: "Asia/Tokyo")!
```

### 2)ロケールを指定する

```swift:
    var calendar = Calendar.current
    calendar.locale = Locale(identifier: "ja")
```

### 3) 暦を指定する

```swift:
    var calendar = Calendar(identifier: .gregorian) // グレゴリオ歴
    var calendar = Calendar(identifier: .japanese)  // 和暦
```

## ②各種値の取得

### 1)年を取得する

```swift:
    var calendar = Calendar.current
    let year = calendar.component(.year, from: date)
```
### 2)月を取得する

```swift:
    var calendar = Calendar.current
    let month = calendar.component(.month, from: date)
```

### 3)日を取得する

```swift:
    var calendar = Calendar.current
    let day = calendar.component(.day, from: date)
```

### 4)時間を取得する

```swift:
    var calendar = Calendar.current
    let hour = calendar.component(.hour, from: date)
```

### 5)分を取得する

```swift:
    var calendar = Calendar.current
    let minute = calendar.component(.minute, from: date)
```

### 6)秒を取得する

```swift:
    var calendar = Calendar.current
    let second = calendar.component(.second, from: date)
```

### 7)曜日を取得する

```swift:
    var calendar = Calendar.current
    let weekday = calendar.component(.weekday, from: date)
```

### 8)月の文字列一覧を取得する

```swift:
    var calendar = Calendar.current
    calendar.locale = Locale(identifier: "ja")
    let monthSymbols = calendar.monthSymbols

    // ["1月", "2月", "3月", "4月", "5月", "6月", "7月", "8月", "9月", "10月", "11月", "12月"]
```

### 9)曜日の文字列一覧を取得する

```swift:
    var calendar = Calendar.current
    calendar.locale = Locale(identifier: "ja")
    let weekdaySymbols = calendar.weekdaySymbols

    // ["日曜日", "月曜日", "火曜日", "水曜日", "木曜日", "金曜日", "土曜日"]
```

### 10)曜日(short)の文字列一覧を取得する

```swift:
    var calendar = Calendar.current
    calendar.locale = Locale(identifier: "ja")
    let shortWeekdaySymbols = calendar.shortWeekdaySymbols

    // ["日", "月", "火", "水", "木", "金", "土"]
```

### 11)月初の日付を取得する

```swift:
    var components = Calendar
        .current.dateComponents([.year, .month, .day, .hour],
                                    from:date)
    components.day = 1
    components.hour = 9
    let startOfDay =  Calendar.current.date(from: comp)!
```

### 12)月末の日付を取得する

```swift:
    var components = Calendar
        .current.dateComponents([.year, .month, .day, .hour],
                                    from:date)
    components.month = 1
    components.day = -1
    components.hour = 9
    let endOfDay Calendar.current.date(byAdding: comp, to: startOfDay!)
```

## ③経過時間

### 1) 経過時間（秒単位）

```swift:
    let components = calendar.dateComponents([.second],
                                             from: fromDate,
                                             to: toDate)
    let passTime =  components.second!
```

### 2) 経過時間（分単位）

```swift:
    let components = calendar.dateComponents([.minute],
                                             from: fromDate,
                                             to: toDate)
    let passTime =  components.minute!
```

### 3) 経過時間（日単位）

```swift:
    let components = calendar.dateComponents([.day],
                                             from: fromDate,
                                             to: toDate)
    let passTime =  components.day!
```

## ④比較

### 1) 年月日が一致するか？

```swift:

    let isSameDate = calendar.isDate(fromDate, inSameDayAs: toDate)
```

### 2) 年が一致するか？

```swift:

    let isSameYear = calendar.compare(fromDate, to: toDate, toGranularity: .year) == .orderedSame
```

### 3) 月が一致するか？

```swift:

    let isSameMonth = calendar.compare(fromDate, to: toDate, toGranularity: .month) == .orderedSame
```

### 4) 年月日時分秒が一致するか？

```swift:
    let isSameDate = fromDate == toDate
```

# DateComponents
## ①日時の操作

### 1)日時の指定

```swift:
    var calendar = Calendar.current
    var compornets = DateComponents()
    compornets.year = 2017
    compornets.month = 10
    compornets.day = 1

    let date = calendar.date(from: compornets)
        
    let dateFormatter = DateFormatter()
    dateFormatter.locale = Locale(identifier: "ja_JP")
    dateFormatter.dateFormat = "yyyy/MM/dd HH:mm:ss"
    print(dateFormatter.string(from: date!)) // 2017/10/01 00:00:00
```

### 2)日時の変更

```swift:
    var calendar = Calendar.current
    var compornets = calendar
        .dateComponents([.year, .month, .day,
                         .hour, .minute, .second,
                         .nanosecond],
                         from: Date())
     compornets.month = 9

        
    let date = calendar.date(from: compornets)
        
    let dateFormatter = DateFormatter()
    dateFormatter.locale = Locale(identifier: "ja_JP")
    dateFormatter.dateFormat = "yyyy/MM/dd HH:mm:ss"
    print(dateFormatter.string(from: date!)) // 2017/09/04 16:54:19
```

## ②各種値の取得

### 1)年月日を取得する

```swift:
    var dataCompornets = calendar
        .dateComponents([.year, .month, .day], from: Date())
        
    print("\(dataCompornets.year!)/\(dataCompornets.month!)/\(dataCompornets.day!)")
```

### 2) 和暦を取得する

```swift:
    let calendar = Calendar(identifier: .japanese)

    var dataCompornets = calendar
        .dateComponents([.year, .month, .day], from: Date())
        
    print("平成\(dataCompornets.year!)年\(dataCompornets.month!)月\(dataCompornets.day!)日")
```

# DateInterval
## ①指定時間後の日付

### 1)開始時間、終了時間の指定なし

```swift:
    let dateInterval = DateInterval()
    print(dateInterval.start)   // 2017-04-04 06:39:13 +0000
    print(dateInterval.end)     // 2017-04-04 06:39:13 +0000
```

### 2)開始時間と間隔を指定する(60秒後）

```swift:
        let dateInterval = DateInterval(start: Date(), duration: 60)
        print(dateInterval.start)   // 2017-04-04 06:39:13 +0000
        print(dateInterval.end)     // 2017-04-04 06:40:13 +0000
```

### 3)開始時間と終了時間を指定する(1時間後）

```swift:
        let endDate = Date().addingTimeInterval(3600)
        let dateInterval = DateInterval(start: Date(), end: endDate)
        
        print(dateInterval.start)   // 2017-04-04 06:39:13 +0000
        print(dateInterval.end)     // 2017-04-04 07:39:13 +0000
```

# まとめ
開発をしていて結構日付を扱うことが多いのではないでしょうか。
有志の方がたくさんまとめて頂いておりますが、自分なりにもまとめてみました。

また、利用シーンがでてきた場合に、追記していきたいと思います。
こういったケースでも使うよというものがあれば、ご教授頂けますと幸いです。