ISO 8601, RFC 3339, UTC समय क्षेत्र के रूप में दिनांक समय टिकट और प्रारूप कैसे बनाएं?


186

आईएसओ 8601 और आरएफसी 3339 के लिए प्रारूप मानकों का उपयोग करते हुए, दिनांक समय टिकट कैसे उत्पन्न करें ?

लक्ष्य एक स्ट्रिंग है जो इस तरह दिखता है:

"2015-01-01T00:00:00.000Z"

प्रारूप:

  • वर्ष, महीना, दिन, "XXXX-XX-XX" के रूप में
  • अक्षर "T" एक विभाजक के रूप में
  • घंटा, मिनट, सेकंड, मिलीसेकंड, "XX: XX: XX.XXX" के रूप में।
  • शून्य ऑफसेट, उर्फ ​​यूटीसी, जीएमटी, ज़ुलु समय के लिए ज़ोन डिज़ाइनर के रूप में "जेड" अक्षर।

सबसे अच्छा मामला:

  • स्विफ्ट स्रोत कोड जो सरल, छोटा और सीधा है।
  • किसी भी अतिरिक्त ढांचे, उपप्रोजेक्ट, कोकोपॉड, सी कोड आदि का उपयोग करने की आवश्यकता नहीं है।

मैंने StackOverflow, Google, Apple, आदि की खोज की है और इस पर एक स्विफ्ट उत्तर नहीं मिला है।

वर्गों है कि ज्यादातर का वादा लगते हैं NSDate, NSDateFormatter, NSTimeZone

संबंधित क्यू एंड ए: मुझे आईओएस में आईएसओ 8601 की तारीख कैसे मिलेगी?

यहाँ मैं अब तक के साथ आया सबसे अच्छा है:

var now = NSDate()
var formatter = NSDateFormatter()
formatter.dateFormat = "yyyy-MM-dd'T'HH:mm:ss.SSS'Z'"
formatter.timeZone = NSTimeZone(forSecondsFromGMT: 0)
println(formatter.stringFromDate(now))

5
ध्यान दें कि iOS10 + SIMPLY INCLUDES ISO 8601 BUILT-IN .. यह आपके लिए बस स्वतः पूर्ण होगा।
फेटी

2
@ फैटी और - यह अंतिम .234Z मिलीसेकंड ज़ुलु / यूटीसी टाइमस्टैम्प का हिस्सा कैसे संभाल सकता है? उत्तर: मैट
लैंग्स

1
@ smat88dd - शानदार टिप, धन्यवाद। मेरे पास कोई सुराग नहीं था कि "एक फॉर्मेटर पर विकल्प", अजीब और जंगली थे!
फेटी

मैं एक समाधान की तलाश कर रहा हूं जो लिनक्स पर काम करता है।
नीयन

@neoneye पुराने संस्करण (प्लेन डेटफॉर्म) का उपयोग करें और कैलेंडर iso8601 को gregorian stackoverflow.com/a/28016692/2303865
सिंह डबस

जवाबों:


392

स्विफ्ट 4 • iOS 11.2.1 या बाद में

extension ISO8601DateFormatter {
    convenience init(_ formatOptions: Options, timeZone: TimeZone = TimeZone(secondsFromGMT: 0)!) {
        self.init()
        self.formatOptions = formatOptions
        self.timeZone = timeZone
    }
}

extension Formatter {
    static let iso8601withFractionalSeconds = ISO8601DateFormatter([.withInternetDateTime, .withFractionalSeconds])
}

extension Date {
    var iso8601withFractionalSeconds: String { return Formatter.iso8601withFractionalSeconds.string(from: self) }
}

extension String {
    var iso8601withFractionalSeconds: Date? { return Formatter.iso8601withFractionalSeconds.date(from: self) }
}

उपयोग:

Date().description(with: .current)  //  Tuesday, February 5, 2019 at 10:35:01 PM Brasilia Summer Time"
let dateString = Date().iso8601withFractionalSeconds   //  "2019-02-06T00:35:01.746Z"

if let date = dateString.iso8601withFractionalSeconds {
    date.description(with: .current) // "Tuesday, February 5, 2019 at 10:35:01 PM Brasilia Summer Time"
    print(date.iso8601withFractionalSeconds)           //  "2019-02-06T00:35:01.746Z\n"
}

iOS 9 • स्विफ्ट 3 या बाद का

extension Formatter {
    static let iso8601withFractionalSeconds: 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
    }()
}

कोडेबल प्रोटोकॉल

यदि आपको कोडेबल प्रोटोकॉल के साथ काम करते समय इस प्रारूप को एनकोड और डीकोड करना होगा तो आप अपनी स्वयं की कस्टम डेट एन्कोडिंग / डिकोडिंग रणनीति बना सकते हैं:

extension JSONDecoder.DateDecodingStrategy {
    static let iso8601withFractionalSeconds = custom {
        let container = try $0.singleValueContainer()
        let string = try container.decode(String.self)
        guard let date = Formatter.iso8601withFractionalSeconds.date(from: string) else {
            throw DecodingError.dataCorruptedError(in: container,
                  debugDescription: "Invalid date: " + string)
        }
        return date
    }
}

और एन्कोडिंग रणनीति

extension JSONEncoder.DateEncodingStrategy {
    static let iso8601withFractionalSeconds = custom {
        var container = $1.singleValueContainer()
        try container.encode(Formatter.iso8601withFractionalSeconds.string(from: $0))
    }
}

खेल का मैदान परीक्षण

let dates = [Date()]   // ["Feb 8, 2019 at 9:48 PM"]

एन्कोडिंग

let encoder = JSONEncoder()
encoder.dateEncodingStrategy = .iso8601withFractionalSeconds
let data = try! encoder.encode(dates)
print(String(data: data, encoding: .utf8)!)

डिकोडिंग

let decoder = JSONDecoder()
decoder.dateDecodingStrategy = .iso8601withFractionalSeconds
let decodedDates = try! decoder.decode([Date].self, from: data)  // ["Feb 8, 2019 at 9:48 PM"]

यहां छवि विवरण दर्ज करें


3
यह विपरीत रूपांतरण एक्सटेंशन जोड़ने के लिए उपयोगी हो जाएगा:extension String { var dateFormattedISO8601: NSDate? {return NSDate.Date.formatterISO8601.dateFromString(self)} }
Vive

1
बस ध्यान दें कि यह थोड़ी सी सटीकता खो देता है इसलिए यह सुनिश्चित करना महत्वपूर्ण है कि तारीखों की समानता उत्पन्न स्ट्रिंग के माध्यम से तुलना की जाती है न कि समय-सारणी। let now = NSDate() let stringFromDate = now.iso8601 let dateFromString = stringFromDate.dateFromISO8601! XCTAssertEqual(now.timeIntervalSince1970, dateFromString.timeIntervalSince1970)
पिक्सेलरविजन

7
कहने की जरूरत नहीं है, अगर आपको मिलीसेकंड की जरूरत नहीं है, तो नया iOS 10 ISO8601DateFormatterप्रक्रिया को सरल बनाता है। मैंने Apple को एक बग रिपोर्ट (27242248) जारी की है, उनसे इस नए फॉर्मैटर को मिलिसेकंड निर्दिष्ट करने की क्षमता प्रदान करने का अनुरोध करने के लिए अनुरोध किया है, यह भी (क्योंकि यह नया फॉर्मेट मिलिसेकंड के बिना हम में से कई के लिए उपयोग का नहीं है)।
रोब

1
में RFC3339 हम एक नोट प्राप्त कर सकते हैं (जैसे) टी "इस वाक्य रचना का उपयोग कर आवेदन पठनीयता के कारण चुन सकते हैं, एक पूर्ण दिनांक और पूर्णकालिक द्वारा अलग निर्दिष्ट करने के लिए:" आईएसओ 8601 परिभाषित करता है दिनांक और समय के द्वारा अलग नोट "। एक अंतरिक्ष चरित्र। " क्या यह Tउदाहरण के बिना दिनांक स्वरूप को कवर करता है 2016-09-21 21:05:10+00:00:?
मानव

3
@LeoDabus हाँ, लेकिन यह "स्विफ्ट iso8601" के लिए पहला परिणाम है। मेरी टिप्पणी अन्य डेवलपर्स को चेतावनी देने के लिए थी जो भविष्य में इस पर आते हैं और ओपी पर निर्देशित नहीं थे।
१०:१० पर यह दृश्य

38

तकनीकी Q & A1480en_US_POSIX में बताए गए स्थान को सेट करना याद रखें । स्विफ्ट 3 में:

let date = Date()
let formatter = DateFormatter()
formatter.locale = Locale(identifier: "en_US_POSIX")
formatter.timeZone = TimeZone(secondsFromGMT: 0)
formatter.dateFormat = "yyyy-MM-dd'T'HH:mm:ss.SSSZZZZZ"
print(formatter.string(from: date))

मुद्दा यह है कि यदि आप एक ऐसे उपकरण पर हैं, जो गैर-ग्रेगोरियन कैलेंडर का उपयोग कर रहा है, तो वर्ष RFC3339 / ISO8601 के अनुरूप नहीं होगा जब तक कि आप और स्ट्रिंग localeको निर्दिष्ट नहीं करते हैं ।timeZonedateFormat

या आप ISO8601DateFormatterसेटिंग localeऔर timeZoneअपने आप को मातम से बाहर निकालने के लिए उपयोग कर सकते हैं :

let date = Date()
let formatter = ISO8601DateFormatter()
formatter.formatOptions.insert(.withFractionalSeconds)  // this is only available effective iOS 11 and macOS 10.13
print(formatter.string(from: date))

स्विफ्ट 2 प्रतिपादन के लिए, इस उत्तर के पिछले संशोधन को देखें ।


हमें en_US_POSIX पर स्थान क्यों सेट करना चाहिए? भले ही हम अमेरिका में नहीं हैं?
mnemonic23

2
ठीक है, आपको कुछ सुसंगत लोकेल की जरूरत है और आईएसओ 8601 / RFC 3999 मानकों का कन्वेंशन वह प्रारूप है जो इसके द्वारा प्रस्तुत किया गया है en_US_POSIX। यह वेब पर तारीखों के आदान-प्रदान के लिए भाषा है । अगर आपके पास तारीख स्ट्रिंग को सहेजने के बाद और स्ट्रिंग को बाद में वापस पढ़ने पर एक कैलेंडर का उपयोग किया गया था, तो आपके पास यह तारीखों का गलत अर्थ नहीं हो सकता है। इसके अलावा, आपको एक ऐसे प्रारूप की आवश्यकता है जो कभी नहीं बदलने की गारंटी देता है (यही कारण है कि आप इसका उपयोग करते हैं en_US_POSIXऔर नहीं करते हैं en_US)। देखें तकनीकी क्यू एंड ए 1480 या अधिक जानकारी के लिए उन आरएफसी / आईएसओ मानक।
रोब

24

यदि आप ISO8601DateFormatter()रेल 4+ JSON फ़ीड की तारीख के साथ उपयोग करना चाहते हैं (और मिल की जरूरत नहीं है), तो आपको सही काम करने के लिए फॉर्मेटर पर कुछ विकल्प निर्धारित करने की आवश्यकता है अन्यथा date(from: string)फ़ंक्शन शून्य वापस आ जाएगा। यहाँ मैं उपयोग कर रहा हूँ:

extension Date {
    init(dateString:String) {
        self = Date.iso8601Formatter.date(from: dateString)!
    }

    static let iso8601Formatter: ISO8601DateFormatter = {
        let formatter = ISO8601DateFormatter()
        formatter.formatOptions = [.withFullDate,
                                          .withTime,
                                          .withDashSeparatorInDate,
                                          .withColonSeparatorInTime]
        return formatter
    }()
}

यहां खेल के मैदान के स्क्रीनशॉट में नहीं विकल्प के छंदों का उपयोग करने का परिणाम है:

यहां छवि विवरण दर्ज करें


आपको विकल्पों में भी शामिल करने की आवश्यकता होगी, .withFractionalSecondsलेकिन मैंने पहले ही कोशिश की थी और यह एक त्रुटि फेंक रहा है libc++abi.dylib: terminating with uncaught exception of type NSException
लियो डबस

@MEnabah स्विफ्ट 4 में यह मेरे लिए ठीक काम करता है। क्या आपको कोई त्रुटि हो रही है?
मैट लॉन्ग

@LeoDabus को आपकी जैसी त्रुटि मिली, क्या आपने उसे हल किया?
फ्रीमैन

कस्टम JSONDecoder DateDecodingStrategy stackoverflow.com/a/46458771/2303865
लियो डबस

@freeman यदि आप अपने सभी अंशों के साथ दिनांक सुरक्षित रखना चाहते हैं, तो मैं आपकी तिथि को सर्वर पर सहेजते / प्राप्त करते समय एक डबल (समय अंतराल से संदर्भ तिथि) का उपयोग करने का सुझाव देता हूं। और .deferredToDateकोडेबल प्रोटोकॉल का उपयोग करते समय डिफ़ॉल्ट तिथि डिकोडिंग रणनीति का उपयोग करें
लियो डबस

6

स्विफ्ट 5

यदि आप iOS 11.0+ / macOS 10.13+ को लक्षित कर रहे हैं, तो आप बस और विकल्प के ISO8601DateFormatterसाथ उपयोग करते हैं, जैसे:withInternetDateTimewithFractionalSeconds

let date = Date()

let iso8601DateFormatter = ISO8601DateFormatter()
iso8601DateFormatter.formatOptions = [.withInternetDateTime, .withFractionalSeconds]
let string = iso8601DateFormatter.string(from: date)

// string looks like "2020-03-04T21:39:02.112Z"

5

एंड्रेस टोरेस मारक्रूइन और लियो डबस की प्रशंसा करने के लिए, मेरे पास एक संस्करण है जो आंशिक सेकंडों को सुरक्षित रखता है। मैं इसे कहीं भी प्रलेखित नहीं कर सकता, लेकिन Apple ने इनपुट और आउटपुट (भले ही SSSSSSS का उपयोग करके निर्दिष्ट किया गया हो, यूनिकोड tr35-31 के विपरीत) माइक्रोसेकंड (परिशुद्धता के 3 अंक) को आंशिक सेकंडों में काट दिया ।

मुझे इस बात पर जोर देना चाहिए कि यह ज्यादातर उपयोग के मामलों के लिए आवश्यक नहीं है । ऑनलाइन तिथियों को आमतौर पर मिलीसेकंड परिशुद्धता की आवश्यकता नहीं होती है, और जब वे करते हैं, तो अक्सर एक अलग डेटा प्रारूप का उपयोग करना बेहतर होता है। लेकिन कभी-कभी किसी विशेष तरीके से पूर्व-मौजूदा प्रणाली के साथ हस्तक्षेप करना चाहिए।

Xcode 8/9 और स्विफ्ट 3.0-3.2

extension Date {
    struct Formatter {
        static let iso8601: DateFormatter = {
            let formatter = DateFormatter()
            formatter.calendar = Calendar(identifier: .iso8601)
            formatter.locale = Locale(identifier: "en_US_POSIX")
            formatter.timeZone = TimeZone(identifier: "UTC")
            formatter.dateFormat = "yyyy-MM-dd'T'HH:mm:ss.SSSSSSXXXXX"
            return formatter
        }()
    }

    var iso8601: String {
        // create base Date format 
         var formatted = DateFormatter.iso8601.string(from: self)

        // Apple returns millisecond precision. find the range of the decimal portion
         if let fractionStart = formatted.range(of: "."),
             let fractionEnd = formatted.index(fractionStart.lowerBound, offsetBy: 7, limitedBy: formatted.endIndex) {
             let fractionRange = fractionStart.lowerBound..<fractionEnd
            // replace the decimal range with our own 6 digit fraction output
             let microseconds = self.timeIntervalSince1970 - floor(self.timeIntervalSince1970)
             var microsecondsStr = String(format: "%.06f", microseconds)
             microsecondsStr.remove(at: microsecondsStr.startIndex)
             formatted.replaceSubrange(fractionRange, with: microsecondsStr)
        }
         return formatted
    }
}

extension String {
    var dateFromISO8601: Date? {
        guard let parsedDate = Date.Formatter.iso8601.date(from: self) else {
            return nil
        }

        var preliminaryDate = Date(timeIntervalSinceReferenceDate: floor(parsedDate.timeIntervalSinceReferenceDate))

        if let fractionStart = self.range(of: "."),
            let fractionEnd = self.index(fractionStart.lowerBound, offsetBy: 7, limitedBy: self.endIndex) {
            let fractionRange = fractionStart.lowerBound..<fractionEnd
            let fractionStr = self.substring(with: fractionRange)

            if var fraction = Double(fractionStr) {
                fraction = Double(floor(1000000*fraction)/1000000)
                preliminaryDate.addTimeInterval(fraction)
            }
        }
        return preliminaryDate
    }
}

यह मेरी राय में सबसे अच्छा जवाब है कि यह सटीक के एक माइक्रोसेकंड स्तर तक पहुंचने की अनुमति देता है जहां अन्य सभी समाधान मिलीसेकंड पर कम हो जाते हैं।
माइकल ए। मैकक्लोस्की

यदि आप अपने सभी अंशों के साथ दिनांक सुरक्षित रखना चाहते हैं, तो आपको अपनी दिनांक को सर्वर पर सहेजते / प्राप्त करते समय बस एक डबल (संदर्भ तिथि के बाद का समय अंतराल) का उपयोग करना चाहिए।
लियो डबस

@LeoDabus हाँ, यदि आप पूरे सिस्टम को नियंत्रित करते हैं और आपको इंटरऑपरेट करने की आवश्यकता नहीं है। जैसा कि मैंने उत्तर में कहा, यह अधिकांश उपयोगकर्ताओं के लिए आवश्यक नहीं है। लेकिन हम सभी का हमेशा वेब APIs में डेटा फॉर्मेटिंग पर नियंत्रण नहीं होता है, और Android और Python (कम से कम) के रूप में, भिन्नात्मक परिशुद्धता के 6 अंकों का संरक्षण होता है, सूट का पालन करना कभी-कभी आवश्यक होता है।
एली बर्क

4

ISO8601DateFormatterIOS10 या नए पर उपयोग करता है ।

DateFormatterIOS9 या पुराने पर उपयोग करता है ।

स्विफ्ट 4

protocol DateFormatterProtocol {
    func string(from date: Date) -> String
    func date(from string: String) -> Date?
}

extension DateFormatter: DateFormatterProtocol {}

@available(iOS 10.0, *)
extension ISO8601DateFormatter: DateFormatterProtocol {}

struct DateFormatterShared {
    static let iso8601: DateFormatterProtocol = {
        if #available(iOS 10, *) {
            return ISO8601DateFormatter()
        } else {
            // iOS 9
            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
        }
    }()
}

3

मेरे मामले में मुझे डायनेमोडीबी - लास्टअपडेटेड कॉलम (यूनिक्स टाइमस्टैम्प) को सामान्य समय में बदलना होगा।

LastUpdated का प्रारंभिक मूल्य था: 1460650607601 - 2016-04-14 16:16:47 +0000 द्वारा नीचे परिवर्तित किया गया:

   if let lastUpdated : String = userObject.lastUpdated {

                let epocTime = NSTimeInterval(lastUpdated)! / 1000 // convert it from milliseconds dividing it by 1000

                let unixTimestamp = NSDate(timeIntervalSince1970: epocTime) //convert unix timestamp to Date
                let dateFormatter = NSDateFormatter()
                dateFormatter.timeZone = NSTimeZone()
                dateFormatter.locale = NSLocale.currentLocale() // NSLocale(localeIdentifier: "en_US_POSIX")
                dateFormatter.dateFormat =  "yyyy-MM-dd'T'HH:mm:ssZZZZZ"
                dateFormatter.dateFromString(String(unixTimestamp))

                let updatedTimeStamp = unixTimestamp
                print(updatedTimeStamp)

            }

3

भविष्य में प्रारूप को बदलने की आवश्यकता हो सकती है जो एक ऐप में हर जगह एक छोटे से सिर में दर्द हो सकता है। कार्यान्वयन को लपेटने के लिए एक वर्ग और प्रोटोकॉल का उपयोग करें, एक स्थान में दिनांक समय प्रारूप कॉल को बदलना सरल होगा। यदि संभव हो तो RFC3339 का उपयोग करें, यह एक अधिक संपूर्ण प्रतिनिधित्व है। DateFormatProtocol और DateFormat निर्भरता इंजेक्शन के लिए बहुत अच्छा है।

class AppDelegate: UIResponder, UIApplicationDelegate {

    internal static let rfc3339DateFormat = "yyyy-MM-dd'T'HH:mm:ssZZZZZ"
    internal static let localeEnUsPosix = "en_US_POSIX"
}

import Foundation

protocol DateFormatProtocol {

    func format(date: NSDate) -> String
    func parse(date: String) -> NSDate?

}


import Foundation

class DateFormat:  DateFormatProtocol {

    func format(date: NSDate) -> String {
        return date.rfc3339
    }

    func parse(date: String) -> NSDate? {
        return date.rfc3339
    }

}


extension NSDate {

    struct Formatter {
        static let rfc3339: NSDateFormatter = {
            let formatter = NSDateFormatter()
            formatter.calendar = NSCalendar(calendarIdentifier: NSCalendarIdentifierISO8601)
            formatter.locale = NSLocale(localeIdentifier: AppDelegate.localeEnUsPosix)
            formatter.timeZone = NSTimeZone(forSecondsFromGMT: 0)
            formatter.dateFormat = rfc3339DateFormat
            return formatter
        }()
    }

    var rfc3339: String { return Formatter.rfc3339.stringFromDate(self) }
}

extension String {
    var rfc3339: NSDate? {
        return NSDate.Formatter.rfc3339.dateFromString(self)
    }
}



class DependencyService: DependencyServiceProtocol {

    private var dateFormat: DateFormatProtocol?

    func setDateFormat(dateFormat: DateFormatProtocol) {
        self.dateFormat = dateFormat
    }

    func getDateFormat() -> DateFormatProtocol {
        if let dateFormatObject = dateFormat {

            return dateFormatObject
        } else {
            let dateFormatObject = DateFormat()
            dateFormat = dateFormatObject

            return dateFormatObject
        }
    }

}

3

एक नया ISO8601DateFormatterवर्ग है कि आप केवल एक पंक्ति के साथ एक स्ट्रिंग बनाते हैं। पीछे की संगतता के लिए मैंने एक पुरानी सी-लाइब्रेरी का उपयोग किया। मुझे उम्मीद है कि यह किसी के लिए उपयोगी है।

स्विफ्ट 3.0

extension Date {
    var iso8601: String {
        if #available(OSX 10.12, iOS 10.0, watchOS 3.0, tvOS 10.0, *) {
            return ISO8601DateFormatter.string(from: self, timeZone: TimeZone.current, formatOptions: .withInternetDateTime)
        } else {
            var buffer = [CChar](repeating: 0, count: 25)
            var time = time_t(self.timeIntervalSince1970)
            strftime_l(&buffer, buffer.count, "%FT%T%z", localtime(&time), nil)
            return String(cString: buffer)
        }
    }
}

1

लियो डबस के संस्करण को पूरक करने के लिए, मैंने स्विफ्ट और ऑब्जेक्टिव-सी लिखी परियोजनाओं के लिए समर्थन जोड़ा, वैकल्पिक मिलीसेकंड के लिए भी समर्थन जोड़ा, शायद यह सबसे अच्छा नहीं है, लेकिन आपको बिंदु मिलेगा:

Xcode 8 और स्विफ्ट 3

extension Date {
    struct Formatter {
        static let iso8601: 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
        }()
    }

    var iso8601: String {
        return Formatter.iso8601.string(from: self)
    }
}


extension String {
    var dateFromISO8601: Date? {
        var data = self
        if self.range(of: ".") == nil {
            // Case where the string doesn't contain the optional milliseconds
            data = data.replacingOccurrences(of: "Z", with: ".000000Z")
        }
        return Date.Formatter.iso8601.date(from: data)
    }
}


extension NSString {
    var dateFromISO8601: Date? {
        return (self as String).dateFromISO8601
    }
}

0

कुछ मैनुअल स्ट्रिंग मास्क या TimeFormatters के बिना

import Foundation

struct DateISO: Codable {
    var date: Date
}

extension Date{
    var isoString: String {
        let encoder = JSONEncoder()
        encoder.dateEncodingStrategy = .iso8601
        guard let data = try? encoder.encode(DateISO(date: self)),
        let json = try? JSONSerialization.jsonObject(with: data, options: .allowFragments) as?  [String: String]
            else { return "" }
        return json?.first?.value ?? ""
    }
}

let dateString = Date().isoString

यह एक अच्छा उत्तर है, लेकिन उपयोग .iso8601में मिलीसेकंड शामिल नहीं होगा।
स्टीफन अरेंटेज़

0

एक वस्तु प्रतिमान में स्वीकार्य उत्तर के आधार पर

class ISO8601Format
{
    let format: ISO8601DateFormatter

    init() {
        let format = ISO8601DateFormatter()
        format.formatOptions = [.withInternetDateTime, .withFractionalSeconds]
        format.timeZone = TimeZone(secondsFromGMT: 0)!
        self.format = format
    }

    func date(from string: String) -> Date {
        guard let date = format.date(from: string) else { fatalError() }
        return date
    }

    func string(from date: Date) -> String { return format.string(from: date) }
}


class ISO8601Time
{
    let date: Date
    let format = ISO8601Format() //FIXME: Duplication

    required init(date: Date) { self.date = date }

    convenience init(string: String) {
        let format = ISO8601Format() //FIXME: Duplication
        let date = format.date(from: string)
        self.init(date: date)
    }

    func concise() -> String { return format.string(from: date) }

    func description() -> String { return date.description(with: .current) }
}

callsite

let now = Date()
let time1 = ISO8601Time(date: now)
print("time1.concise(): \(time1.concise())")
print("time1: \(time1.description())")


let time2 = ISO8601Time(string: "2020-03-24T23:16:17.661Z")
print("time2.concise(): \(time2.concise())")
print("time2: \(time2.description())")
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.