आप एक स्विफ्ट डेट ऑब्जेक्ट कैसे बनाते हैं?


156

आप स्विफ्ट xcode में किसी दिनांक से दिनांक ऑब्जेक्ट कैसे बनाते हैं।

जावास्क्रिप्ट में आप क्या करेंगे: var day = new Date('2014-05-20');


10
NSDateऑब्जेक्टिव-सी की तरह ही इस्तेमाल करें ?
रम्मडी

जवाबों:


263

स्विफ्ट का अपना एक Dateप्रकार है। उपयोग करने की आवश्यकता नहीं है NSDate

स्विफ्ट में डेट और टाइम बनाना

स्विफ्ट में, दिनांक और समय 64-बिट फ़्लोटिंग पॉइंट संख्या में संग्रहीत किए जाते हैं, जो 1 जनवरी 2001 की 00:00:00 UTC की संदर्भ तिथि के बाद सेकंड की संख्या को मापता है । यह Dateसंरचना में व्यक्त किया गया है । निम्नलिखित आपको वर्तमान तिथि और समय देगा:

let currentDateTime = Date()

अन्य दिनांक-समय बनाने के लिए, आप निम्न विधियों में से एक का उपयोग कर सकते हैं।

विधि 1

यदि आप 2001 की संदर्भ तिथि से पहले या बाद में सेकंड की संख्या जानते हैं, तो आप इसका उपयोग कर सकते हैं।

let someDateTime = Date(timeIntervalSinceReferenceDate: -123456789.0) // Feb 2, 1997, 10:26 AM

विधि 2

बेशक, ए, बनाने के लिए वर्षों, महीनों, दिनों और घंटों (बजाय सापेक्ष सेकंड) जैसी चीजों का उपयोग करना आसान होगा Date। इसके लिए आप DateComponentsघटकों को निर्दिष्ट करने और फिर Calendarतिथि बनाने के लिए उपयोग कर सकते हैं । Calendarदेता है Dateसंदर्भ। अन्यथा, यह कैसे पता चलेगा कि इसे किस समय क्षेत्र या कैलेंडर में व्यक्त करना है?

// Specify date components
var dateComponents = DateComponents()
dateComponents.year = 1980
dateComponents.month = 7
dateComponents.day = 11
dateComponents.timeZone = TimeZone(abbreviation: "JST") // Japan Standard Time
dateComponents.hour = 8
dateComponents.minute = 34

// Create date from components
let userCalendar = Calendar.current // user calendar
let someDateTime = userCalendar.date(from: dateComponents)

अन्य समय क्षेत्र के संक्षिप्त विवरण यहां देखे जा सकते हैं । यदि आप उस रिक्त को छोड़ देते हैं, तो उपयोगकर्ता के समय क्षेत्र का उपयोग करने के लिए डिफ़ॉल्ट है।

विधि 3

सबसे रसीला तरीका (लेकिन जरूरी नहीं कि सबसे अच्छा) का उपयोग किया जा सके DateFormatter

let formatter = DateFormatter()
formatter.dateFormat = "yyyy/MM/dd HH:mm"
let someDateTime = formatter.date(from: "2016/10/08 22:31")

यूनिकोड तकनीकी मानकों अन्य प्रारूपों के प्रदर्शन कि DateFormatterसमर्थन करता है।

टिप्पणियाँ

दिनांक और समय को पठनीय प्रारूप में कैसे प्रदर्शित किया जाए, इसके लिए मेरा पूरा उत्तर देखें । इन बेहतरीन लेखों को भी पढ़ें:


118

यह मौजूदा NSDateवर्ग के विस्तार का उपयोग करके सबसे अच्छा किया जाता है ।

निम्न एक्सटेंशन एक नया इनिशलाइज़र जोड़ता है जो आपके द्वारा निर्दिष्ट प्रारूप में दिनांक स्ट्रिंग का उपयोग करके वर्तमान लोकल में एक दिनांक बनाएगा।

extension NSDate
{
    convenience
      init(dateString:String) {
      let dateStringFormatter = NSDateFormatter()
      dateStringFormatter.dateFormat = "yyyy-MM-dd"
      dateStringFormatter.locale = NSLocale(localeIdentifier: "en_US_POSIX")
      let d = dateStringFormatter.dateFromString(dateString)!
      self.init(timeInterval:0, sinceDate:d)
    }
 }

अब आप बस स्विफ्ट से एक एनएसडी बना सकते हैं:

NSDate(dateString:"2014-06-06")

कृपया ध्यान दें कि यह कार्यान्वयन NSDateFormatter को कैश नहीं करता है, जिसे आप प्रदर्शन कारणों से करना चाह सकते हैं यदि आप NSDateइस तरह से कई s बनाने की अपेक्षा करते हैं ।

कृपया यह भी ध्यान दें कि यदि आप NSDateएक स्ट्रिंग में सही ढंग से पार्स नहीं किया जा सकता है, तो इसे लागू करने का प्रयास करने पर यह कार्यान्वयन बस दुर्घटनाग्रस्त हो जाएगा। इसका कारण यह है कि वैकल्पिक मूल्य के जबरन जारी किए गए मान से dateFromString। यदि आप nilखराब पर्स पर वापस जाना चाहते हैं, तो आप आदर्श रूप से एक असफल शुरुआती का उपयोग करेंगे; लेकिन आप स्विफ्ट 1.2 में एक सीमा के कारण अब (जून 2015) ऐसा नहीं कर सकते हैं, इसलिए आप अगले सबसे अच्छा विकल्प एक क्लास फैक्टरी विधि का उपयोग करना चाहते हैं।

एक अधिक विस्तृत उदाहरण, जो दोनों मुद्दों को संबोधित करता है, यहां है: https://gist.github.com/algal/09b08515460b7bd229fa


स्विफ्ट 5 के लिए अपडेट

extension Date {
    init(_ dateString:String) {
        let dateStringFormatter = DateFormatter()
        dateStringFormatter.dateFormat = "yyyy-MM-dd"
        dateStringFormatter.locale = NSLocale(localeIdentifier: "en_US_POSIX") as Locale
        let date = dateStringFormatter.date(from: dateString)!
        self.init(timeInterval:0, since:date)
    }
}

9
तो "सुविधा" शब्द यहाँ क्या है?
जेम्स बर्न

18
यह इंगित करता है कि विस्तार एक इनिशियलाइज़र प्रदान कर रहा है जो वास्तव में पहले से मौजूद नामित इनिशियलाइज़र को इनिशियलाइज़ेशन दर्शाता है, जो कि इस मामले में NSDate.init (timeInterval:, afterDate :) इनिशियलाइज़र है। यह द स्विफ्ट प्रोग्रामिंग लैंग्वेज बुक के पेज 275 में वर्णित है।
algal

1
ऊपर दिए गए कोड में एक दोष मुझे लगता है NSDateFormatterकि फ़ंक्शन एक्सेस किए जाने के बाद हर बार फिर से बना रहा है। जैसा कि दिनांक स्वरूपण गाइड बताता है कि दिनांक फ़ॉर्मेटर बनाना सस्ता ऑपरेशन नहीं है । इसके अलावा, iOS7 से क्लास थ्रेड-सुरक्षित है, इसलिए कोई भी इसे सभी NSDateएक्सटेंशन के लिए सुरक्षित रूप से उपयोग कर सकता है ।
येविन दुबिनिन

@eugenedubinin सही है। इसलिए मैंने कहा "यह कार्यान्वयन NSDateFormatter को कैश नहीं करता है, जिसे आप प्रदर्शन कारणों से करना चाह सकते हैं"।
algal

1
स्विफ्ट 1.2 में सीमा क्या है? फीचर "फेल्ट इनिशियलाइज़र" स्विफ्ट 1.1 के बाद से उपलब्ध है
फ्रैंकलिन यू

48

स्विफ्ट का अपना दिनांक प्रकार नहीं है, लेकिन आप मौजूदा कोको NSDateप्रकार का उपयोग करते हैं , जैसे:

class Date {

    class func from(year: Int, month: Int, day: Int) -> Date {
        let gregorianCalendar = NSCalendar(calendarIdentifier: .gregorian)!

        var dateComponents = DateComponents()
        dateComponents.year = year
        dateComponents.month = month
        dateComponents.day = day

        let date = gregorianCalendar.date(from: dateComponents)!
        return date
    }

    class func parse(_ string: String, format: String = "yyyy-MM-dd") -> Date {
        let dateFormatter = DateFormatter()
        dateFormatter.timeZone = NSTimeZone.default
        dateFormatter.dateFormat = format

        let date = dateFormatter.date(from: string)!
        return date
    }
}

जिसे आप उपयोग कर सकते हैं जैसे:

var date = Date.parse("2014-05-20")
var date = Date.from(year: 2014, month: 05, day: 20)

मुझे लाइन बदलनी थी: var date = gregorian? .DateFromCompords (c) लेकिन मुझे समझ नहीं आ रहा है, और parse return dateFmt.dateFromString भी शिकायत कर रहा है। कोई सुराग? आह, मैंने NSDate से NSDate में फ़ंक्शन का रिटर्न प्रकार बदल दिया है? जो इसे संकलित करने देता है। लेकिन मुझे यकीन नहीं है कि यह अशक्त होने की आवश्यकता क्यों है।
सीनेटर

1
@ TheSenator NSCalendar init एक वैकल्पिक (?) लौटाता है, इसलिए gregorian एक वैकल्पिक (?) है। वैकल्पिक विकल्प तक पहुँचने की आवश्यकता है ताकि इसे gregorian तक पहुँचाया जा सके। dateFromCoompords विकल्प gregorian (NSCalendar) से मान को अनपैक करने के लिए वैकल्पिक श्रृंखलन है। यहाँ
iluvatar_GR

NSGregorianCalendar को iOS 8 के रूप में दर्शाया गया है इसलिए इसके बजाय NSCalendarIdentifierGregorian का उपयोग करें
एडम शूरवीरों

2
@ सीनेटर ने शिकायत की है कि स्विफ्ट में डेट स्ट्रक्चर है, और यह कोड क्लास के रूप में फिर से तारीख को दोबारा बताता है। तो यू कुछ करना चाहिए: 'एक्सटेंशन डेट' और 'स्टैटिक फंक'
ज़ापोरोज़्चेंको ऑलेक्ज़ेंडर

तारीख के लिए पार्स स्ट्रिंग के बारे में एक ज्ञापन। एक स्ट्रिंग "1979-07-01" NSDateFormatterविधि के लिए "yyyy-MM-dd" के साथ date(from:)। यह लौट आता है nil। मैं इस मुद्दे को fabric.io क्रैश लॉग में पाया।
एकोएलियू

12

यहाँ मैंने इसे स्विफ्ट 4.2 में कैसे किया:

extension Date {

    /// Create a date from specified parameters
    ///
    /// - Parameters:
    ///   - year: The desired year
    ///   - month: The desired month
    ///   - day: The desired day
    /// - Returns: A `Date` object
    static func from(year: Int, month: Int, day: Int) -> Date? {
        let calendar = Calendar(identifier: .gregorian)
        var dateComponents = DateComponents()
        dateComponents.year = year
        dateComponents.month = month
        dateComponents.day = day
        return calendar.date(from: dateComponents) ?? nil
    }
}

उपयोग:

let marsOpportunityLaunchDate = Date.from(year: 2003, month: 07, day: 07)

हालांकि मैं एक तारीख के रूप में '15' पास कर रहा हूं, जो तारीख वापस आ गई है वह 14 वीं देता है? विचार?
ल्यूक ज़मिट

@LukeZammit एक समय-सारणी जोड़ेंdateComponents
एड्रियन

यह कोई भाग्य के साथ की कोशिश की - dateCompords.timeZone = TimeZone.current, विचार कृपया?
ल्यूक ज़मिट


4

में, स्विफ्ट 3.0 में आपने इस तरह से दिनांक वस्तु निर्धारित की है।

extension Date
{
    init(dateString:String) {
        let dateStringFormatter = DateFormatter()
        dateStringFormatter.dateFormat = "yyyy-MM-dd"
        dateStringFormatter.locale = Locale(identifier: "en_US_POSIX")
        let d = dateStringFormatter.date(from: dateString)!
        self(timeInterval:0, since:d)
    }
}

@ Zonker.in.Geneva हर जगह आप चाहते हैं। अलग फ़ाइल बनाएं, इसे "एक्सटेंशन", आईडीके कहें।
ज़ापोरोज़ेन्को ऑलेक्ज़ेंडर

2

व्यक्तिगत रूप से मुझे लगता है कि यह एक प्रारंभिक आरम्भिक होना चाहिए:

extension Date {

    init?(dateString: String) {
        let dateStringFormatter = DateFormatter()
        dateStringFormatter.dateFormat = "yyyy-MM-dd"
        if let d = dateStringFormatter.date(from: dateString) {
            self.init(timeInterval: 0, since: d)
        } else {
            return nil
        }
    }
}

अन्यथा एक अमान्य प्रारूप वाली स्ट्रिंग एक अपवाद को बढ़ाएगी।


2

@Mythz उत्तर के अनुसार, मैं swift3सिंटैक्स का उपयोग करके उनके एक्सटेंशन के अपडेट किए गए संस्करण को पोस्ट करने का निर्णय लेता हूं ।

extension Date {
    static func from(_ year: Int, _ month: Int, _ day: Int) -> Date?
    {
        let gregorianCalendar = Calendar(identifier: .gregorian)
        let dateComponents = DateComponents(calendar: gregorianCalendar, year: year, month: month, day: day)
        return gregorianCalendar.date(from: dateComponents)
    }
}

मैं parseविधि का उपयोग नहीं करता , लेकिन अगर किसी को ज़रूरत हो, तो मैं इस पोस्ट को अपडेट करूंगा।


1

मुझे अक्सर एक स्थान से दूसरे के लिए समय मूल्यों के साथ दिनांक मानों को संयोजित करने की आवश्यकता होती है। मैंने इसे पूरा करने के लिए एक सहायक कार्य लिखा।

let startDateTimeComponents = NSDateComponents()
startDateTimeComponents.year = NSCalendar.currentCalendar().components(NSCalendarUnit.Year, fromDate: date).year
startDateTimeComponents.month = NSCalendar.currentCalendar().components(NSCalendarUnit.Month, fromDate: date).month
startDateTimeComponents.day = NSCalendar.currentCalendar().components(NSCalendarUnit.Day, fromDate: date).day
startDateTimeComponents.hour = NSCalendar.currentCalendar().components(NSCalendarUnit.Hour, fromDate: time).hour
startDateTimeComponents.minute = NSCalendar.currentCalendar().components(NSCalendarUnit.Minute, fromDate: time).minute
let startDateCalendar = NSCalendar(identifier: NSCalendarIdentifierGregorian)
combinedDateTime = startDateCalendar!.dateFromComponents(startDateTimeComponents)!

0

एप्पल के डेटा फॉर्मेटिंग गाइड के अनुसार

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

और जब मैं @ लोन से सहमत हूं कि यह उपलब्ध नहीं होना चाहिए, जब आप बीज डेटा दर्ज करते हैं, तो हम एक ऐसा हो सकता है जो कि उपलब्ध नहीं है (जैसे वहां है) UIImage(imageLiteralResourceName:) )।

तो यहाँ मेरा दृष्टिकोण है:

extension DateFormatter {
  static let yyyyMMdd: DateFormatter = {
    let formatter = DateFormatter()
    formatter.dateFormat = "yyyy-MM-dd"
    formatter.calendar = Calendar(identifier: .iso8601)
    formatter.timeZone = TimeZone(secondsFromGMT: 0)
    formatter.locale = Locale(identifier: "en_US_POSIX")
    return formatter
  }()
}

extension Date {
    init?(yyyyMMdd: String) {
        guard let date = DateFormatter.yyyyMMdd.date(from: yyyyMMdd) else { return nil }
        self.init(timeInterval: 0, since: date)
    }

    init(dateLiteralString yyyyMMdd: String) {
        let date = DateFormatter.yyyyMMdd.date(from: yyyyMMdd)!
        self.init(timeInterval: 0, since: date)
    }
}

और अब बस फोन करने का आनंद लें:

// For seed data
Date(dateLiteralString: "2020-03-30")

// When parsing data
guard let date = Date(yyyyMMdd: "2020-03-30") else { return nil }
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.