date('c')
を介してPHPでISO 8601日付文字列(たとえば、2004-02-12T15:19:21+00:00
)を取得するのは簡単ですが、Objective-C(iPhone)ではどのように取得しますか?同様の短い方法がありますか?
これがlongの方法です。
NSDateFormatter* dateFormatter = [[[NSDateFormatter alloc] init] autorelease];
dateFormatter.dateFormat = @"yyyy-MM-dd'T'HH:mm:ssZ";
NSDate *now = [NSDate date];
NSString *formattedDateString = [dateFormatter stringFromDate:now];
NSLog(@"ISO-8601 date: %@", formattedDateString);
// Output: ISO-8601 date: 2013-04-27T13:27:50-0700
とても中心的な何かのためのひどい多くのリグマロールのようです。
NSDateFormatter
を使用します。
NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
NSLocale *enUSPOSIXLocale = [NSLocale localeWithLocaleIdentifier:@"en_US_POSIX"];
[dateFormatter setLocale:enUSPOSIXLocale];
[dateFormatter setDateFormat:@"yyyy-MM-dd'T'HH:mm:ssZZZZZ"];
[dateFormatter setCalendar:[NSCalendar calendarWithIdentifier:NSCalendarIdentifierGregorian]];
NSDate *now = [NSDate date];
NSString *iso8601String = [dateFormatter stringFromDate:now];
そして、Swiftでは:
let dateFormatter = DateFormatter()
let enUSPosixLocale = Locale(identifier: "en_US_POSIX")
dateFormatter.locale = enUSPosixLocale
dateFormatter.dateFormat = "yyyy-MM-dd'T'HH:mm:ssZZZZZ"
dateFormatter.calendar = Calendar(identifier: .gregorian)
let iso8601String = dateFormatter.string(from: Date())
iOS 10では、これを処理するための新しい NSISO8601DateFormatter
クラスが導入されています。 Swift 3を使用している場合、コードは次のようになります。
let formatter = ISO8601DateFormatter()
let date = formatter.date(from: "2016-08-26T12:39:00Z")
let string = formatter.string(from: Date())
Maddyの答えを補完するものとして、タイムゾーン形式は、単一の「Z」(RFC 822形式)ではなく、ISO 8601の「ZZZZZ」(Zの5倍)でなければなりません。少なくともiOS 6。
( http://www.unicode.org/reports/tr35/tr35-25.html#Date_Format_Patterns を参照)
よく見落とされがちな問題は、ISO 8601形式の文字列にはミリ秒がある場合とない場合があることです。
つまり、「2016-12-31T23:59:59.9999999」と「2016-12-01T00:00:00」はどちらも合法ですが、静的型の日付フォーマッターを使用している場合は、どちらかが解析されません。
iOS 10から開始して、ISO 8601日付文字列のすべてのバリエーションを処理するISO8601DateFormatter
を使用する必要があります。以下の例を参照してください。
let date = Date()
var string: String
let formatter = ISO8601DateFormatter()
string = formatter.string(from: date)
let GMT = TimeZone(abbreviation: "GMT")
let options: ISO8601DateFormatOptions = [.withInternetDateTime, .withDashSeparatorInDate, .withColonSeparatorInTime, .withTimeZone]
string = ISO8601DateFormatter.string(from: date, timeZone: GMT, formatOptions: options)
iOS 9以下では、複数のデータフォーマッタで次のアプローチを使用します。
この微妙な違いを取り除いて、ケースとアブストラクトの両方をカバーする答えは見つかりませんでした。これに対処するソリューションは次のとおりです。
extension DateFormatter {
static let iso8601DateFormatter: DateFormatter = {
let enUSPOSIXLocale = Locale(identifier: "en_US_POSIX")
let iso8601DateFormatter = DateFormatter()
iso8601DateFormatter.locale = enUSPOSIXLocale
iso8601DateFormatter.dateFormat = "yyyy-MM-dd'T'HH:mm:ss.SSS'Z'"
iso8601DateFormatter.timeZone = TimeZone(secondsFromGMT: 0)
return iso8601DateFormatter
}()
static let iso8601WithoutMillisecondsDateFormatter: DateFormatter = {
let enUSPOSIXLocale = Locale(identifier: "en_US_POSIX")
let iso8601DateFormatter = DateFormatter()
iso8601DateFormatter.locale = enUSPOSIXLocale
iso8601DateFormatter.dateFormat = "yyyy-MM-dd'T'HH:mm:ss'Z'"
iso8601DateFormatter.timeZone = TimeZone(secondsFromGMT: 0)
return iso8601DateFormatter
}()
static func date(fromISO8601String string: String) -> Date? {
if let dateWithMilliseconds = iso8601DateFormatter.date(from: string) {
return dateWithMilliseconds
}
if let dateWithoutMilliseconds = iso8601WithoutMillisecondsDateFormatter.date(from: string) {
return dateWithoutMilliseconds
}
return nil
}
}
使用法:
let dateToString = "2016-12-31T23:59:59.9999999"
let dateTo = DateFormatter.date(fromISO8601String: dateToString)
// dateTo: 2016-12-31 23:59:59 +0000
let dateFromString = "2016-12-01T00:00:00"
let dateFrom = DateFormatter.date(fromISO8601String: dateFromString)
// dateFrom: 2016-12-01 00:00:00 +0000
また、日付フォーマッタについて Appleの記事 を確認することもお勧めします。
NSDateのSam Soffeeのカテゴリを使用してください here 。そのコードをプロジェクトに追加すると、それ以降はNSDateで単一のメソッドを使用できます。
- (NSString *)sam_ISO8601String
純粋なCで記述されているため、NSDateFormatterアプローチよりもはるかに高速な1行だけではありません。
IS8601 から、問題は表現とタイムゾーンです
year-month-day time timezone
T
を使用できます有効な文字列は次のとおりです
2016-04-08T10:25:30Z
2016-04-08 11:25:30+0100
2016-04-08 202530GMT+1000
20160408 08:25:30-02:00
2016-04-08 11:25:30 +0100
ソリューション
NSDateFormatter
だからここで私が使用している形式は onmyway133 ISO8601
let formatter = NSDateFormatter()
formatter.locale = NSLocale(localeIdentifier: "en_US_POSIX")
formatter.dateFormat = "yyyyMMdd HHmmssZ"
Z
識別子について 日付フィールドシンボルテーブル
Z: The ISO8601 basic format with hours, minutes and optional seconds fields. The format is equivalent to RFC 822 zone format (when optional seconds field is absent)
locale
について ロケール設定を使用したデータのフォーマット
ロケールは、ユーザーの優先言語ではなく、特定のユーザーの書式設定の選択肢を表します。これらはしばしば同じですが、異なる場合があります。たとえば、ドイツに住んでいるネイティブスピーカーは、言語として英語を選択し、地域としてドイツを選択します。
en_US_POSIX
について 技術的なQ&A QA1480 NSDateFormatterとインターネット日付
一方、固定形式の日付を使用している場合は、まず日付フォーマッターのロケールを固定形式に適したものに設定する必要があります。ほとんどの場合、選択する最適なロケールは「en_US_POSIX」です。これは、ユーザー設定とシステム設定の両方に関係なく、米国英語の結果が得られるように特別に設計されたロケールです。 「en_US_POSIX」も時間的に不変です(米国が将来のある時点で日付のフォーマット方法を変更した場合、「en_US」は新しい動作を反映するように変更されますが、「en_US_POSIX」は変更されません)、およびマシン間( 「en_US_POSIX」は、iOS上でもOS X上でも、他のプラットフォーム上でも同じように機能します)。
興味深い関連質問
FoundationフレームワークのNSISO8601DateFormatterを使用するだけです。
let isoDateFormatter = ISO8601DateFormatter()
print("ISO8601 string: \(isoDateFormatter.string(from: Date()))")
// ISO8601 string: 2018-03-21T19:11:46Z
https://developer.Apple.com/documentation/foundation/nsiso8601dateformatter?language=objc
この要点に基づいて: https://github.com/justinmakaila/NSDate-ISO-8601/blob/master/NSDateISO8601.Swift 、次の方法を使用してNSDateをISO 8601日付文字列に変換できますyyyy-MM-dd'T'HH:mm:ss.SSSZの形式
-(NSString *)getISO8601String
{
static NSDateFormatter *formatter = nil;
if (!formatter)
{
formatter = [[NSDateFormatter alloc] init];
[formatter setLocale: [NSLocale localeWithLocaleIdentifier:@"en_US_POSIX"]];
formatter.timeZone = [NSTimeZone timeZoneWithAbbreviation: @"UTC"];
[formatter setDateFormat:@"yyyy-MM-dd'T'HH:mm:ss.SSS"];
}
NSString *iso8601String = [formatter stringFromDate: self];
return [iso8601String stringByAppendingString: @"Z"];
}
これは少し簡単で、日付をUTCに入れます。
extension NSDate
{
func iso8601() -> String
{
let dateFormatter = NSDateFormatter()
dateFormatter.timeZone = NSTimeZone(name: "UTC")
let iso8601String = dateFormatter.stringFromDate(NSDate())
return iso8601String
}
}
let date = NSDate().iso8601()