[ios] iOS에서 ISO 8601 날짜를 얻으려면 어떻게해야합니까?

ISO 8601 날짜 문자열 (예 : 2004-02-12T15:19:21+00:00PHP에서date('c') Objective-C (iPhone)에서는 어떻게 얻습니까? 그것을 수행하는 비슷한 짧은 방법이 있습니까?

여기에 내가 찾은 방법이 있습니다.

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 부터 ISO8601DateFormatterISO 8601 날짜 문자열의 모든 변형을 처리 하는 것을 사용해야 합니다. 아래 예를 참조하십시오.

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)

들어 아이폰 OS 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의 카테고리를 사용 하십시오 . 해당 코드를 프로젝트에 추가하면 NSDate에서 단일 메서드를 사용할 수 있습니다.

- (NSString *)sam_ISO8601String

순수한 C로 작성 되었기 때문에 NSDateFormatter 접근 방식보다 훨씬 빠른 한 줄일뿐만 아니라


답변

에서 IS8601 , 문제는 표현 및 시간대입니다

  • ISO 8601 = year-month-day time timezone
  • 날짜 및 시간에는 기본 (YYYYMMDD, hhmmss, …) 및 확장 형식 (YYYY-MM-DD, hh : mm : ss, …)이 있습니다.
  • 시간대는 Zulu, 오프셋 또는 GMT 일 수 있습니다.
  • 날짜 및 시간 구분 기호는 공백이거나 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