SwiftのDateFormatter
(Objective-CではNSDateFormatter
)の使い方をまとめました。
日付から文字列を取得する
規定のStyleを使う
一番簡単なのはdateStyle
とtimeStyle
を利用する方法。日付、時刻それぞれについて長め、標準、短め、なしの4つのスタイルを選択すると、localeに応じた適切な文字列を生成できる。
let dateFormatter = DateFormatter()
dateFormatter.dateStyle = .medium
dateFormatter.timeStyle = .none
let dateString = dateFormatter.string(from: Date())
print(dateString)
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に準拠する。
let dateFormatter = DateFormatter()
dateFormatter.dateFormat = "yyyy-MM-dd 'at' HH:mm"
let date = Date()
let dateString = dateFormatter.string(from: date)
print(dateString)
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。
dateFormatter.locale = Locale(identifier: "en_US_POSIX")
dateFormatter.locale = [[NSLocale alloc] initWithLocaleIdentifier:@"en_US_POSIX"];
Localeに応じたカスタムフォーマット
表示する要素を自由に選択しつつ、ユーザーのlocaleにあわせた適切なフォーマットで表示したい場合は、dateFormat(fromTemplate:options:locale:)
を使って適切なフォーマット文字列を取得する。
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)
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な日付文字列をパースする例
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)
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
にしてフォーマットが固定であることを担保している。