年、月、日、曜日、時、分、秒といった、日付時刻の各フィールドの値に個別にアクセスするには、Date構造体に、DateComponents構造体、Calendar構造体という3つの型を組み合わせて使用します。

■ 日付時刻の各フィールドの値を管理するDateComponents型

まず、日付時刻のフィールドの値を個別に管理する構造体であるDateComponents型について説明しましょう。このDateComponents型のインスタンスに年や月、日といった値を個別に設定し、それをもとにCalendar型のメソッドを実行することで、Date型のインスタンスが作成できるのです。
DateComponents型は、年、日、時といった日付時刻の各フィールドの値をInt型のプロパティとして管理するだけのシンプルな構造体です。用意されているのは、個々のフィールドの値にアクセスするプロパティのみです。値はすべてInt型の整数値です

★DateComponentsの主なプロパティ
プロパティ 説明
era 時代
year 年
month 月
day 日
hour 時
minute 分
second 秒
week 週
weekday 曜日

たとえば、「weekday」(曜日)は「1」から始まる数値です(「0」からではない点に注意してください)。グレゴリオ暦の場合には、日曜日を「1」として、以下、月曜日が「2」、火曜日が「3」と続き、最後の土曜日が「7」となります。
なお、DateComponentでは、必ずしもすべての日付時刻のフィールドを設定する必要はありません。たとえば、時刻が不要なら設定しなくてもかまいません。各プロパティはオプショナル型で、設定しない状態ではnilとなります。

次に、yearとmonthのみを設定して結果を確認する例を示します。

var dateComps = DateComponents()
dateComps.year = 2017
dateComps.month = 12

print(dateComps.year) // Optional(2017)
print(dateComps.month) // Optional(12)
print(dateComps.day) // nil
print(dateComps.hour) // nil

print(dateComps) // year: 2017 month: 12 isLeapMonth: false

■ 暦の管理はCalendar構造体で

DateComponentsオブジェクトでは、日付時刻フィールドの値は、暦によって異なります。たとえば、年のフィールドは、グレゴリオ暦(西暦)での2015年は、和暦では平成27年になります。Swiftでは、暦をCalendar構造体で管理します。
DateComponentsオブジェクトのフィールドの値がどの暦によるものなのかを、Calendarオブジェクトで指定する必要があるわけです。
現在システムで設定されている暦はcurrentタイププロパティで取得できます。

let cal = Calendar.current // gregorian (current)

上記のようにデフォルトではグレゴリオ歴になっています。

□ Date、DateComponents、Calendarの役割について

Date、DateComponents、Calendarの3つの型を連携する場合の、それぞれの役割を説明しておきましょう。まず、Dateは、コンピュータの内部表現で日付時刻を管理しています。そして、年や月、日、時間といったフィールドを個別に管理するのがDateComponents型です。各フィールドの値は、使用する暦によって異なる可能性があります。そこでCalendar型で暦を設定するわけです。Calendar型のメソッドを経由して、DateオブジェクトとDateComponentsオブジェクトの中身を相互変換すると考えてもよいでしょう。

■ 指定した日時にDateオブジェクトを生成する

(1)Calendarオブジェクトを用意する
(2)日時のデータを設定したDateComponentsオブジェクトを用意する
(3)CalendarクラスのdateFromComponents(_:)メソッドを、DateComponentsオブジェクトを引数に実行する
手順(3)では、Calendar型のdate(from:)ソッドを使用してDateクラスのインスタンスを生成します。

メソッド: date(from:)
宣言:func date(from components: DateComponents) -> Date?
説明: DateComponentsオブジェクトからDateオブジェクトを生成する

次に「2016年9月16日」の日付データをDateComponentsオブジェクトとして用意し、デフォルトのCalendarクラスのインスタンスを利用して、Dateクラスのインスタンスを生成する例を示します。

// システムのカレンダーを取得
let cal = Calendar.current

// 指定した日付のDateComponentsを生成
var dateComps = DateComponents()
dateComps.year = 2016
dateComps.month = 9
dateComps.day = 16

// Dateオブジェクトを生成
var theDate = cal.date(from: dateComps)

let dateFormatter = DateFormatter()
dateFormatter.locale = Locale(identifier: "ja_JP")
dateFormatter.dateFormat = "yyyy年MM月dd日(EEEE)"
print(dateFormatter.string(from: theDate!)) // 2016年09月16日(金曜日)

■ Dateオブジェクトから日付時刻を個別に取り出す

Date、DateComponents、Calendarの3つの型を連携する例として、続いてDateオブジェクトからDateComponentオブジェクトを取得する例を示しましょう。
それにはCalendar構造体に用意されているdateComponents(_:from:)メソッドを使用します。

メソッド:dateComponents(_:from:)
宣言:func dateComponents(_ components: Set<Calendar.Component>, from date: Date) -> DateComponent
説明: DateオブジェクトからDateComponentsオブジェクトを生成する

最初の引数にはCalendar.Component列挙型の次のような値を集合(Set)にして指定します。

★Calendar.Component列挙型の主な値
era
year
month
day
weekday
hour
minute
second

たとえば、年、月、日を指定するには次のようにします。

[.year, .month, .day],

*component(_:from:)メソッドを使用すると各フィールドの値を個別に取り出せます。

□ 現在の年、月、日、時、分を取り出す

それではcomponents(_:, fromDate:)メソッドの実際の使用例として、現在の日付時刻を管理するDateオブジェクト「now」から、年、月、日、時、分のフィールドを取り出して表示する例を示しましょう

// 現在の日時を取得
var now = Date()

// システムのカレンダーを取得
let cal = Calendar.current

// 現在時刻のDateComponentsを取り出す
var dataComps = cal.dateComponents([.year, .month, .day, .hour, .minute], from: now)

print("\(dataComps.year!)年\(dataComps.month!)月\(dataComps.day!)日 \(dataComps.hour!)時\(dataComps.minute!)分") // 2016年9月16日 21時35分

■ 暦を指定する

Calendar型には、引数で暦を指定して初期化するイニシャライザが用意されています。

イニシャライザ
宣言:init(identifier: Calendar.Identifier)
説明: インスタンスを指定した暦で初期化する

引数にはネストされた列挙型であるCalendar.Identifierの値を指定します。たとえばグレゴリオ歴の場合には「gregorian」和暦の場合には「japanese」を指定します。

var jCal = Calendar(identifier: Calendar.Identifier.japanese)

次に、これを使用して、現在の日時を和暦で表示する例を示します。

// 現在の日時を取得
var now = Date()

// システムのカレンダーを取得
//let cal = Calendar.current
var cal = Calendar(identifier: Calendar.Identifier.japanese)

// 現在時刻のDateComponentsを取り出す
var dataComps = cal.dateComponents([.year, .month, .day, .hour, .minute], from: now)

print("平成\(dataComps.year!)年\(dataComps.month!)月\(dataComps.day!)日 \(dataComps.hour!)時\(dataComps.minute!)分") // 平成28年9月16日 21時42分