मैं इसे पार्स करने की कोशिश कर रहा हूं
2017-01-23T10:12:31.484Z
iOS 10
द्वारा प्रदान की गई देशी ISO8601DateFormatter
कक्षा का उपयोग करना लेकिन हमेशा विफल रहता है। यदि स्ट्रिंग में मिलीसेकंड नहीं है, तो Date
ऑब्जेक्ट बिना किसी समस्या के बनाया जाता है।
मैंने यह कोशिश की है और कई options
संयोजन लेकिन हमेशा विफल रहता है ...
let formatter = ISO8601DateFormatter()
formatter.timeZone = TimeZone(secondsFromGMT: 0)
formatter.formatOptions = [.withInternetDateTime, .withDashSeparatorInDate, .withColonSeparatorInTime, .withColonSeparatorInTimeZone, .withFullTime]
कोई विचार? धन्यवाद!
4 जवाब
MacOS 10.13 / iOS 11 से पहले ISO8601DateFormatter
मिलीसेकंड सहित डेट स्ट्रिंग्स का समर्थन नहीं करता है।
नियमित अभिव्यक्ति के साथ मिलीसेकंड भाग को हटाने के लिए एक समाधान है।
let isoDateString = "2017-01-23T10:12:31.484Z"
let trimmedIsoString = isoDateString.replacingOccurrences(of: "\\.\\d+", with: "", options: .regularExpression)
let formatter = ISO8601DateFormatter()
let date = formatter.date(from: trimmedIsoString)
MacOS 10.13+ / iOS 11+ में भिन्नात्मक सेकंड का समर्थन करने के लिए एक नया विकल्प जोड़ा गया है:
static var withFractionalSeconds: ISO8601DateFormatter.Options { get }
let isoDateString = "2017-01-23T10:12:31.484Z"
let formatter = ISO8601DateFormatter()
formatter.formatOptions = [.withInternetDateTime, .withFractionalSeconds]
let date = formatter.date(from: isoDateString)
उन लोगों के लिए जो अभी तक iOS 11 पर जाने के लिए तैयार नहीं हैं, आप मिलीसेकंड को संभालने के लिए हमेशा अपना खुद का फॉर्मेटर बना सकते हैं, जैसे:
extension DateFormatter {
static var iSO8601DateWithMillisec: DateFormatter {
let dateFormatter = DateFormatter()
dateFormatter.dateFormat = "yyyy-MM-dd'T'HH:mm:ss.SSSZ"
return dateFormatter
}
}
उपयोग:
let formater = DateFormatter.iSO8601DateWithMillisec
let date = formater.date(from: "2017-01-23T10:12:31.484Z")!
print(date) // output: 2017-01-23 10:12:31 +0000
इनपुट स्ट्रिंग से मिलीसेकंड को अलग करने के लिए रेगेक्स लिखने से यह थोड़ा अधिक सुरुचिपूर्ण है।
शायद यह थोड़ा अलग प्रारूपों को डीकोड करने में मदद करेगा:
extension JSONDecoder {
enum DateDecodeError: String, Error {
case invalidDate
}
static var bestDateAttemptDecoder: JSONDecoder {
let decoder = JSONDecoder()
decoder.dateDecodingStrategy = .custom({ (decoder) -> Date in
let container = try decoder.singleValueContainer()
if let dateSecs = try? container.decode(Double.self) {
return Date(timeIntervalSince1970: dateSecs)
}
if let dateSecs = try? container.decode(UInt.self) {
return Date(timeIntervalSince1970: TimeInterval(dateSecs))
}
let dateStr = try container.decode(String.self)
let isoFormatter = ISO8601DateFormatter()
isoFormatter.formatOptions = [.withInternetDateTime, .withFractionalSeconds]
if let date = isoFormatter.date(from: dateStr) {
return date
}
isoFormatter.formatOptions = [.withInternetDateTime ]
if let date = isoFormatter.date(from: dateStr) {
return date
}
log.warning("Cannot decode date");
throw DateDecodeError.invalidDate
})
return decoder
}
}
प्रेषक: https://gist.github.com/th3m477/442a0d1da6354dd3b84e3b71df5dca6a
मुझे कुछ महीने पहले इसी मुद्दे का सामना करना पड़ा था। और यहाँ संदर्भ के लिए मेरा समाधान है:
// *****************************************
// MARK: - Formatter extension
// *****************************************
extension Formatter {
static let iso8601: ISO8601DateFormatter = {
let formatter = ISO8601DateFormatter()
formatter.timeZone = TimeZone.current
formatter.formatOptions = [.withInternetDateTime, .withFractionalSeconds]
return formatter
}()
static let iso8601NoSecond: ISO8601DateFormatter = {
let formatter = ISO8601DateFormatter()
formatter.timeZone = TimeZone.current
formatter.formatOptions = [.withInternetDateTime]
return formatter
}()
}
// *****************************************
// MARK: - ISO8601 helper
// *****************************************
func getDateFrom(DateString8601 dateString:String) -> Date?
{
if let date = Formatter.iso8601.date(from: dateString) {
return date
}
if let date = Formatter.iso8601NoSecond.date(from: dateString) {
return date
}
return nil
}
// *****************************************
// usage
// *****************************************
let d = getDateFrom(DateString8601: "2017-01-23T10:12:31.484Z")
print("2017-01-23T10:12:31.484Z millis= ", d?.timeIntervalSinceReferenceDate)
let d2 = getDateFrom(DateString8601: "2017-01-23T10:12:31Z")
print("2017-01-23T10:12:31Z millis= ", d2?.timeIntervalSinceReferenceDate)
// *****************************************
// result
// *****************************************
2017-01-23T10:12:31.484Z millis= Optional(506859151.48399997)
2017-01-23T10:12:31Z millis= Optional(506859151.0)
formatter.timeZone = TimeZone.current
गलत है। आपको क्या लगता है कि Apple ने ISO8601DateFormatter टाइमज़ोन को GMT से शून्य सेकंड में डिफ़ॉल्ट क्यों बनाया?
संबंधित सवाल
जुड़े हुए प्रश्न
नए सवाल
ios
iOS, Apple iPhone, iPod टच और iPad पर चलने वाला मोबाइल ऑपरेटिंग सिस्टम है। IOS प्लेटफॉर्म पर प्रोग्रामिंग से संबंधित प्रश्नों के लिए इस टैग [ios] का उपयोग करें। उन प्रोग्रामिंग भाषाओं के लिए विशिष्ट मुद्दों के लिए संबंधित टैग [उद्देश्य-सी] और [स्विफ्ट] का उपयोग करें।
dateFormat
का उपयोग करना तरीका है, लेकिन मैं आईओएस 10 के मूल वर्ग का उपयोग करना चाहता हूं ... :(