Edited at

DateFormatterの使い方まとめ

More than 1 year has passed since last update.

SwiftのDateFormatter(Objective-CではNSDateFormatter)の使い方をまとめました。


日付から文字列を取得する


規定のStyleを使う

一番簡単なのはdateStyletimeStyleを利用する方法。日付、時刻それぞれについて長め、標準、短め、なしの4つのスタイルを選択すると、localeに応じた適切な文字列を生成できる。


Swift

let dateFormatter = DateFormatter()

dateFormatter.dateStyle = .medium
dateFormatter.timeStyle = .none

let dateString = dateFormatter.string(from: Date())
print(dateString)



Objective-C

NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];

dateFormatter.dateStyle = NSDateFormatterMediumStyle;
dateFormatter.timeStyle = NSDateFormatterNoStyle;

NSString *dateString = [dateFormatter stringFromDate:[NSDate date]];
NSLog(@"%@", dateString);



  • ja_JPのとき: 2013/11/26

  • en_USのとき: Nov 26, 2013


固定のカスタムフォーマット

自由にフォーマットを指定したい場合、dateFormatで指定可能。書式はUnicode Technical Standard #35に準拠する。


Swift

let dateFormatter = DateFormatter()

dateFormatter.dateFormat = "yyyy-MM-dd 'at' HH:mm"

let date = Date()

let dateString = dateFormatter.string(from: date)
print(dateString)



Objective-C

NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];

dateFormatter.dateFormat = @"yyyy-MM-dd 'at' HH:mm";

NSDate *date = [NSDate date];

NSString *dateString = [dateFormatter stringFromDate:date];
NSLog(@"%@", dateString);


注意点


  • ユーザーが選択したカレンダー設定が反映される

  • 時刻の24時間表記のユーザー設定によって指定したフォーマットが上書きされる

上記コードでlocaleがja_JPの場合、期待される結果はおそらく「2013-11-26 at 23:21」であるが、カレンダーを「和暦」、24時間表示をオフに設定していると、結果は「0025-11-26 at 午後11:21」となってしまう。

これを防ぎたければ、以下のようにlocaleをen_US_POSIXに指定する。これは書式が変わらないことが保証されている特別なlocale。


Swift

dateFormatter.locale = Locale(identifier: "en_US_POSIX")



Objective-C

dateFormatter.locale = [[NSLocale alloc] initWithLocaleIdentifier:@"en_US_POSIX"];



Localeに応じたカスタムフォーマット

表示する要素を自由に選択しつつ、ユーザーのlocaleにあわせた適切なフォーマットで表示したい場合は、dateFormat(fromTemplate:options:locale:)を使って適切なフォーマット文字列を取得する。


Swift

guard let formatString = DateFormatter.dateFormat(fromTemplate: "MMMdd", options: 0, locale: Locale.current) else { fatalError() }

print(formatString)

let dateFormatter = DateFormatter()
dateFormatter.dateFormat = formatString

let date = Date()

let dateString = dateFormatter.string(from: date)
print(dateString)



Objective-C

NSString *formatString = [NSDateFormatter dateFormatFromTemplate:@"MMMdd" options:0 locale:[NSLocale currentLocale]];

NSLog(@"%@", formatString);

NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
dateFormatter.dateFormat = formatString;

NSDate *date = [NSDate date];

NSString *dateString = [dateFormatter stringFromDate:date];
NSLog(@"%@", dateString);



  • ja_JPのとき


    • フォーマット: M月dd日

    • 結果: 11月26日



  • en_USのとき


    • フォーマット: MMM dd

    • 結果: Nov 26



  • en_GBのとき


    • フォーマット: dd MMM

    • 結果: 26 Nov




文字列から日付を取得する

RFC 3339な日付文字列をパースする例


Swift

let dateFormatter = DateFormatter()

dateFormatter.locale = Locale(identifier: "en_US_POSIX")
dateFormatter.dateFormat = "yyyy'-'MM'-'dd'T'HH':'mm':'ss'Z'"
dateFormatter.timeZone = TimeZone(secondsFromGMT: 0)

let string = "1985-04-12T23:20:50Z"
let date = dateFormatter.date(from: string)



Objective-C

NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];

dateFormatter.locale = [[NSLocale alloc] initWithLocaleIdentifier:@"en_US_POSIX"];
dateFormatter.dateFormat = @"yyyy'-'MM'-'dd'T'HH':'mm':'ss'Z'";
dateFormatter.timeZone = [NSTimeZone timeZoneForSecondsFromGMT:0];

NSString *string = @"1985-04-12T23:20:50Z";
NSDate *date = [dateFormatter dateFromString:string];


ここでもlocaleをen_US_POSIXにしてフォーマットが固定であることを担保している。


参考リンク