Help us understand the problem. What is going on with this article?

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にしてフォーマットが固定であることを担保している。

参考リンク

gonsee
カレンダーシェアアプリ「TimeTree」のiOSアプリを開発しています。個人では「陣痛時計」、「ごみの日アラーム」というアプリをリリースしています。Perfumeエバンジェリスト。
https://simplebeep.net/iphone-apps
jubileeworks
「毎日に、新しい"なくてはならない"を創る」を経営理念に掲げ、共有カレンダーサービス TimeTree の開発・運営をしています。
https://timetreeapp.com/
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away