SwiftUI において、日付 の形式で記述された 文字列を Date 型として扱う際には DateFormatter を用いて 型変換 をすると便利です。今回は、実際に画面上で 文字列 , フォーマット , ロケール を指定しながら内部でどのように取り扱われているのかを サンプル コード とともに見ていきます。
Swift 5, Xcode 12.5.1
はじめに
SwiftUI において、文字列を日付型( Date )に変換するには DateFormatter を用いるところまではすんなり理解できたのですが、実際の サンプル をあまり発見できず モヤモヤ していたので実際に サンプル コード を作って確かめてみました。
日付文字列 -> Date() 変換
入力 フィールド の準備
まずは、 入力 フィールド を TextField を用いて作成していきます。変換したい日付の文字列 (dateString) とその文字列がどのような形式であるか (dateFormat) を用意します。
struct DateFormatterView: View {
@State private var dateString = "2020/12/31"
@State private var dateFormat = "yyyy/MM/dd"
var body: some View {
VStack {
Section(header: Text("Date String")) {
TextField("date string", text: $dateString)
.padding(5)
.border(Color.red, width: 2.0)
}
Section(header: Text("Date Format")) {
TextField("date format", text: $dateFormat)
.padding(5)
.border(Color.blue, width: 2.0)
}
}
}
とりあえず、 入力 フィールド には初期値として適当な値を設定しておきます。
日付文字列 -> Date 型変換 処理の実装
次に、Date 型への変換処理部分を作成します。
private func printDate() {
print("=====")
print("input Date String: ", dateString)
print("input Date Format: ", dateFormat)
let dateFormatter = DateFormatter()
dateFormatter.dateFormat = dateFormat
if let date = dateFormatter.date(from: dateString) {
print("Date(): ", date)
} else {
print("ERROR to convert")
}
print("=====")
}
最初に確認用に TextField に入力された値を出力した後、 DateFormatter() を用いて初期化した変数を作成します。この変数に、本画面に設定されている日付の フォーマット をdateFormatとして登録します。
日付文字列の内容を dateFormatter.date を用いてdate 変数に格納し、そのdate変数の内容を出力しています。
合わせて、初期処理と各入力値の変更を リアルタイム に反映する処理を VStack の モディファイア として追記します。
.onAppear() {
printDate()
}
.onChange(of: dateString, perform: { value in
printDate()
})
.onChange(of: dateFormat, perform: { value in
printDate()
})
上記で作成できる画面は以下のようになります。
必要な情報をこの画面で入力し、出力結果は上述の通り、 Xcode 内の デバッグ ウィンドウ に表示させる仕組みとなっています。

それでは、実際に動かしてみます。
日付文字列 -> Date 型変換 処理 の実行
まずは、 コード に直接記載した デフォルト 値での出力をみていきます。
===== input Date String: 2020/12/31 input Date Format: yyyy/MM/dd Date(): 2020-12-30 15:00:00 +0000 =====
入力した日付と、 Date() に変換した日付が異なっていますが、これは プログラム 実行環境が JST(UTC +9) の環境で実施していたことが影響しています。
時刻を入力していないため、時刻が補完された、”2020年12月31日0時0分という文字列”を、”指定された ロケール であるja_JP(これは、UTC+9)”として取り込みます。この値は、 UTC に変換すると、9時間分戻した”2020年12月30日15時0分”という値となり、このような出力結果となります。
日付 フォーマット を変えてみる
試しに日付 フォーマット を変更した際の動作をみていきます。”2018″ を “yy” で変換してみると、以下のように 2018 年として変換できています。

===== input Date String: 2018/12/31 input Date Format: yy/MM/dd Date() : 2018-12-30 15:00:00 +0000 =====
サンプルコード 全体
import SwiftUI
struct DateFormatterView: View {
@State private var dateString = "2020/12/31"
@State private var dateFormat = "yyyy/MM/dd"
var body: some View {
VStack {
Section(header: Text("Date String")) {
TextField("date string", text: $dateString)
.padding(5)
.border(Color.red, width: 2.0)
}
Section(header: Text("Date Format")) {
TextField("date format", text: $dateFormat)
.padding(5)
.border(Color.blue, width: 2.0)
}
}
.onAppear() {
printDate()
}
.onChange(of: dateString, perform: { value in
printDate()
})
.onChange(of: dateFormat, perform: { value in
printDate()
})
}
private func printDate() {
print("=====")
print("input Date String: ", dateString)
print("input Date Format: ", dateFormat)
let dateFormatter = DateFormatter()
dateFormatter.dateFormat = dateFormat
if let date = dateFormatter.date(from: dateString) {
print("Date() : ", date)
} else {
print("dateFormatter Failed")
}
print("=====")
}
}
まとめ
- 日付文字列の フォーマット を dateFormatter() の dateFormat に セット
- dateFormatter() の date を用いて Date 型に 変換
- 日付は プログラム 実行環境に従って処理される
