【Swift】DateFormatterの使い方!書式や日付形式の調整方法

この記事からわかること

  • SwiftDateFormatterとは?
  • 日付日時書式変更方法
  • dateStyle/timeStyleの設定値
  • プロパティ種類
  • Date()構造体当日以外の日付を取得する

index

[open]

\ アプリをリリースしました /

みんなの誕生日

友達や家族の誕生日をメモ!通知も届く-みんなの誕生日-

posted withアプリーチ

Swiftで日付を表示する際の書式や形式を定義できるDateFormatterの使い方をまとめていきたいと思います。

DateFormatterの使い方

日付や時間を表示する際の形式は状況や環境によって別の形を使うことが多いです。swiftでは日時のフォーマットを定義できるDateFormatterを使うことで簡単に書式や形式の操作が可能になっています。

暦(西暦:.gregorianや和暦:.japanese)やロケール、タイムゾーンは明示的に任意の値に変更でき、設定しない場合は端末に設定されている値が使用されます。

let df = DateFormatter()
df.calendar = Calendar(identifier: .gregorian)
df.locale = Locale(identifier: "ja_JP")
df.timeZone = TimeZone(identifier: "Asia/Tokyo")

DateFormatterのプロパティには日付の形式を操作できるdateStyleと時間の形式を操作できるtimeStyleが用意されています。これらのプロパティはlocaleプロパティにセットされているロケールに準じたフォーマットに自動変換してくれます。

let df = DateFormatter()
df.locale = Locale(identifier: "ja_JP")
df.dateStyle = .full
df.timeStyle = .short
print(df.string(from: Date()))
// "2022年6月19日 日曜日 15:21\n"

DateFormatterはインスタンス化して使用するので変数dfの中に格納しておきます。その後設定したいロケール(地域などのこと)をlocaleにセットします。

dateStyletimeStyleで書式を決めたらstringプロパティに表示させたい日付を渡します。現在時刻を渡すにはDate()で取得できます。

DateFormatterの使い方〜まとめ〜

  1. DateFormatter()を変数に格納
  2. ロケールを設定
  3. 日付と時間の書式を設定
  4. stringプロパティの引数に日時を渡す

おすすめ記事:【Swift】Date構造体の使い方!日付の計算や比較方法

dateStyleやtimeStyleに設定できる書式

dateStyletimeStyleには決められた.full/.long/.medium/.short/.noneの5つの書式から選択して設定します。

df.dateStyle = .full   // 2022年6月19日 日曜日 
df.dateStyle = .long   // 2022年6月19日
df.dateStyle = .medium // 2022/06/19 
df.dateStyle = .short  // 2022/06/19
df.dateStyle = .none   // 出力しない

df.timeStyle = .full   // 15時29分41秒 日本標準時
df.timeStyle = .long   // 15:30:27 JST
df.timeStyle = .medium // 15:30:40
df.timeStyle = .short  // 15:30
df.timeStyle = .none   // 出力しない

日時の書式を自由にカスタマイズする:dateFormat

dateFormatプロパティを使うとより自由に日時形式をカスタマイズすることができます。

let df = DateFormatter()
df.locale = Locale(identifier: "ja_JP")
df.calendar = Calendar(identifier: .japanese)
df.dateFormat = "令和yy年M月dd日 EEEE HH時mm分"
print(df.string(from: Date()))
// 令和4年6月19日 日曜日 15時41分\n"

年月日や時間はyyEEEEなどといったフォーマットパターンがあらかじめ定義されています。上記のように令和◯年といった和暦(4年)で年数を取得する場合はcalendarプロパティの値を変更します。デフォルトは西暦(2022年)になっています。

日時のフォーマットパターン

和暦(元号)で表示させる

追記:2023/2/22

年数を西暦ではなく和暦かつ元号も表示させたい場合は日時のフォーマットでGyと指定することで表示させることができました。

let df = DateFormatter()
df.locale = Locale(identifier: "ja_JP")
df.calendar = Calendar(identifier: .japanese)
df.dateFormat = "Gy年M月dd日 EEEE HH時mm分"
print(df.string(from: Date()))
// 令和4年6月19日 日曜日 15時41分\n"

近日の場合は「今日」や「昨日」と表示させる

doesRelativeDateFormattingプロパティにtrueを渡すと当日の日付なら「今日」といったような表示にさせることができます。対応しているのは±2日で「一昨日」〜「明後日」までが表示されます。

let df = DateFormatter()
df.locale = Locale(identifier: "ja_JP")
df.dateStyle = .full
df.timeStyle = .none
df.doesRelativeDateFormatting = true
print(df.string(from: Date()))
// 今日

任意の日付文字列でDateFormatterを使用する

文字列として渡された任意の日付情報をDateFormatterとして操作してみます。渡された日付文字列とdateFormatで指定した形式が異なるとエラーに、オプショナル型になるようで!で強制的にアンラップしないとエラーになりました。

let df = DateFormatter()
let now = "2022/6/18"
df.dateFormat = "yyyy/MM/dd 誕生"
df.locale = Locale(identifier: "ja_JP")
let date = df.date(from: now)!
print(df.string(from: date))
// 2022/06/18 誕生

Date()構造体で現在時刻以外を指定する

Date()構造体を使って当日以外の日付を指定するにはtimeIntervalSinceNowに差分を渡せばOKです。60 * 60 * 24秒 * 分 * 時です。

let df = DateFormatter()
let tomorrow = Date(timeIntervalSinceNow: 60 * 60 * 24)
df.dateFormat = "yyyy/MM/dd"
df.locale = Locale(identifier: "ja_JP")
print(df.string(from: tomorrow))
// "2022/06/20" 

実際のアプリ開発で日付を用いてみる

使い方は理解できたので実際にSwift UIでiOSアプリを開発する際に使用してみたいと思います。

今回は構造体のプロパティとして日付情報を保持させたいと思います。その日付情報は指定せずともデフォルト値として現在の時刻が格納され、表示するのは時間のみに整形するように作っていきます。

作成したい日付のポイント

Xcodeで新規のプロジェクトを作成したら最初から用意されている「ContentView.swift」とは別に構造体を定義するためのSwiftファイルを作成します。

中には以下のように記述します。

  struct CashData: Identifiable,Codable{

    var id = UUID()             // 一意の値
    var cash:Int                // 金額情報
    var memo:String = ""        // MEMO
    // 初期値に現在の日付
    var time:String = { 
        
        let df = DateFormatter()
        df.calendar = Calendar(identifier: .gregorian)
        df.locale = Locale(identifier: "ja_JP")
        df.timeZone = TimeZone(identifier: "Asia/Tokyo")
        df.dateStyle = .none
        df.timeStyle = .short

        return df.string(from: Date())

    }()
}

今回の構造体はプロパティはListを使って表示するため「Identifiableプロトコル」に、別JSON形式に変換したいため「Codableプロトコル」に準拠させてきますがDateFormatterとは無関係であり、重要になってくるのは以下の部分です。

var time:String = { 
        
        let df = DateFormatter()
        df.calendar = Calendar(identifier: .gregorian)
        df.locale = Locale(identifier: "ja_JP")
        df.timeZone = TimeZone(identifier: "Asia/Tokyo")
        df.dateStyle = .none
        df.timeStyle = .short
        
        return df.string(from: Date())

    }()

最初はDateFormatterをインスタンス化してロケールやタイムゾーンを設定する処理を構造体の外に記述しましたが、「Expressions are not allowed at the top level」というエラーになってしまいました。

なのでプロパティをコンピューテッドプロパティにして、中でロケールなどの初期設定を行います。あとはこれまでの使い方に倣って記述するだけです。

今回は敢えて文字列型として返しましたが、日付型の場合に返す方法がよく分からず力技でなんとか返すこともできました。良い方法があったら教えてください。

return df.date(from: df.string(from: Date()))

まだまだ勉強中ですので間違っている点や至らぬ点がありましたら教えていただけると助かります。

ご覧いただきありがとうございました。

searchbox

スポンサー

ProFile

ame

趣味:読書,プログラミング学習,サイト制作,ブログ

IT嫌いを克服するためにITパスを取得しようと勉強してからサイト制作が趣味に変わりました笑
今はCMSを使わずこのサイトを完全自作でサイト運営中〜

New Article

index