2017-11-28 10 views
0

これは私が解読しようとしているものです:JSONDecoderでこの形式を解析するにはどうすればよいですか? (YYYY-MM-dd'T'HH:MM:ss.SSSSSSS)

{"MessageDate":"2017-11-28T05:04:40.9611765"} 

私はJSON構造の残りの部分を省略しました。

JSONDecoderは、その日付形式をDateオブジェクトに解析するにはどうすればよいですか?

は、これは私がこれまで試したものです:

extension Formatter 
{ 
    static let dotNetDateTime: DateFormatter = { 
     let formatter = DateFormatter() 
     formatter.dateFormat = "yyyy-MM-dd'T'HH:mm:ss" 
     return formatter 
    }() 

    /// https://stackoverflow.com/a/46458771/8462094 
    static let dotNetDateTimeISO8601: DateFormatter = { 
     let formatter = DateFormatter() 
     formatter.calendar = Calendar(identifier: .iso8601) 
     formatter.locale = Locale(identifier: "en_US_POSIX") 
     formatter.timeZone = TimeZone(secondsFromGMT: 0) 
     formatter.dateFormat = "yyyy-MM-dd'T'HH:mm:ss.SSSXXXXX" 
     return formatter 
    }() 

    /// https://stackoverflow.com/a/46458771/8462094 
    static let dotNetDateTimeISO8601NoMS: DateFormatter = { 
     let formatter = DateFormatter() 
     formatter.calendar = Calendar(identifier: .iso8601) 
     formatter.locale = Locale(identifier: "en_US_POSIX") 
     formatter.timeZone = TimeZone(secondsFromGMT: 0) 
     formatter.dateFormat = "yyyy-MM-dd'T'HH:mm:ssXXXXX" 
     return formatter 
    }() 

    static let dotNetDateTimeCustom: DateFormatter = { 
     let formatter = DateFormatter() 
     formatter.locale = Locale(identifier: "en_US_POSIX") 
     formatter.dateFormat = "yyyy-MM-dd'T'HH:mm:ss.SSSSSSS" 
     return formatter 
    }() 

    static let iso8601Full: DateFormatter = { 
     let formatter = DateFormatter() 
     formatter.dateFormat = "yyyy-MM-dd'T'HH:mm:ss.SSSXXXX" 
     formatter.calendar = Calendar(identifier: .iso8601) 
     formatter.timeZone = TimeZone(secondsFromGMT: 0) 
     formatter.locale = Locale(identifier: "en_US_POSIX") 
     return formatter 
    }() 
} 

それらのいくつかは、他のスタックオーバーフローのポストからとられています。
私はまた、上記以外の多くの日付デコード戦略を試みました。
私は何時間もインターネットで解決策を探しました。
私はUnicode documentation for date format patternsを見ました。
私は別の友人の助けを借りてきました。

私は日付文字列の最後に7桁の浮動小数点が疑いがありますが、それはどのように対処するのか分かりません。
多分私は本当に小さいものを見逃しています。目の別のセットはいいだろう。

お手数ですが、ありがとうございます。

私はパースだ実際のコードを含める必要がありますね。

let attempt1 = JSONDecoder() 
attempt1.dateDecodingStrategy = .formatted(Formatter.dotNetDateTime) 
let attempt2 = JSONDecoder() 
attempt2.dateDecodingStrategy = .formatted(Formatter.dotNetDateTimeISO8601) 
//And more attempt initializations 
... 
print(String(data: data, encoding: .utf8)!) 
if let deser = try? attempt1.decode(MessageThreads.self, from: data) 
{ 
    return onDone(deser, nil) 
} 
if let deser = try? attempt2.decode(MessageThreads.self, from: data) 
{ 
    return onDone(deser, nil) 
} 
//And more attempts 
... 

答えて

2

はそれを手に入れました。デバッグする必要があるときに、プレイグラウンドを使用することがあります。

extension Formatter 
{ 
    static let dotNetDateTimeWithMilliseconds: DateFormatter = { 
     let formatter = DateFormatter() 
     formatter.locale = Locale(identifier: "en_US_POSIX") 
     formatter.dateFormat = "yyyy-MM-dd'T'HH:mm:ss.S" 
     return formatter 
    }() 
} 

ただ1つの.Sで解析するだけで十分です。

編集:
@Leo Dabusはロケールを含める必要があると言いました。私はそれを追加しました。あなたの助けにThanx Leo!

+1

ロケールをen_US_POSIXに設定してください。もう1つのことは、サーバーからの日付文字列がUTC時間ではないことを確認していることですか? –

+0

Btwこれは、日付の解析時にも分数秒の残りの部分を破棄します。あなたがdoubleを使用するためにAPIを構築している人で、jsonのtimeIntervalSinceReferenceDateを渡す場合は、 –

+0

私は 'en_US_POSIX'が何をするのか本当に分かりません。私はそれがロケールを米国に強制することは知っていますが、それはどういう意味ですか?サーバーが米国に拠点を置いている場合は、ロケールを強制しますか?サーバーがヨーロッパなどにある場合は、別のロケールを使用する必要がありますか?また、 '.SSSSSS'のようにSを追加し続ければ、分数秒の残りはまだ破棄されます。 (私はAPIを構築していません(しかし、UNIXや何かの時からAPIがミリ秒を使用したいと思っています) –

関連する問題