दो NSDates के बीच अंतर प्राप्त करना (महीनों / दिनों / घंटों / मिनट / सेकंड)


206

मैं वर्तमान तारीख NSDate()और time();उदाहरण के लिए PHP कॉल से एक तारीख के बीच अंतर प्राप्त करने की कोशिश कर रहा हूं NSDate(timeIntervalSinceReferenceDate: 1417147270):। मैं दो तिथियों के बीच समय के अंतर को कैसे प्राप्त करूं? मैं एक ऐसा कार्य करना चाहता हूँ जो दो तिथियों की तुलना करता है और if(seconds > 60)फिर मिनट, if(minutes > 60)रिटर्न घंटे और if(hours > 24)वापसी के दिन और इसी तरह से होता है।

मुझे इस बारे में कैसे बर्ताव करना चाहिए?

संपादित करें: वर्तमान स्वीकृत उत्तर ने वही किया है जो मैं करना चाहता था। मैं इसे दो तिथियों के बीच के समय के लिए आसान उपयोग के लिए सुझाता हूं जो कि PHP time()फ़ंक्शन का उपयोग करता है। यदि आप PHP से विशेष रूप से परिचित नहीं हैं, तो 1 जनवरी, 1970 से कुछ सेकंड का समय है। यह PHP में बैकएंड के लिए फायदेमंद है। यदि शायद आप NodeJS जैसे बैकएंड का उपयोग कर रहे हैं, तो आप नीचे दिए गए कुछ अन्य विकल्पों पर विचार करना चाह सकते हैं।


2
मुझे एहसास है कि यह पुरानी तरह का है, लेकिन आप अंतर के साथ क्या करना चाहते हैं? उदाहरण के लिए, यदि आप उपयोगकर्ता के लिए एक स्ट्रिंग प्रारूपित करना चाहते हैं, तो आपको उपयोग करना चाहिए NSDateComponentsFormatter। यह बहुत विन्यास योग्य है, जिससे आपको उचित परिणाम प्राप्त करने की अनुमति मिलती है (उदाहरण के लिए .maximumUnitCount = 1)।
केन थॉम्सिस

वास्तव में, आप जो करने का इरादा रखते हैं वह प्रश्न नितांत आवश्यक है। इस बात पर विचार करें कि एक महीना २, दिन जितना कम हो सकता है, या एक दिन ३१ दिन से अधिक हो सकता है।
gnasher729

जवाबों:


510

Xcode 8.3 • स्विफ्ट 3.1 या बाद में

आप कैलेंडर का उपयोग अपनी तिथि गणनाओं को करने के लिए एक एक्सटेंशन बनाने में मदद करने के लिए कर सकते हैं:

extension Date {
    /// Returns the amount of years from another date
    func years(from date: Date) -> Int {
        return Calendar.current.dateComponents([.year], from: date, to: self).year ?? 0
    }
    /// Returns the amount of months from another date
    func months(from date: Date) -> Int {
        return Calendar.current.dateComponents([.month], from: date, to: self).month ?? 0
    }
    /// Returns the amount of weeks from another date
    func weeks(from date: Date) -> Int {
        return Calendar.current.dateComponents([.weekOfMonth], from: date, to: self).weekOfMonth ?? 0
    }
    /// Returns the amount of days from another date
    func days(from date: Date) -> Int {
        return Calendar.current.dateComponents([.day], from: date, to: self).day ?? 0
    }
    /// Returns the amount of hours from another date
    func hours(from date: Date) -> Int {
        return Calendar.current.dateComponents([.hour], from: date, to: self).hour ?? 0
    }
    /// Returns the amount of minutes from another date
    func minutes(from date: Date) -> Int {
        return Calendar.current.dateComponents([.minute], from: date, to: self).minute ?? 0
    }
    /// Returns the amount of seconds from another date
    func seconds(from date: Date) -> Int {
        return Calendar.current.dateComponents([.second], from: date, to: self).second ?? 0
    }
    /// Returns the a custom time interval description from another date
    func offset(from date: Date) -> String {
        if years(from: date)   > 0 { return "\(years(from: date))y"   }
        if months(from: date)  > 0 { return "\(months(from: date))M"  }
        if weeks(from: date)   > 0 { return "\(weeks(from: date))w"   }
        if days(from: date)    > 0 { return "\(days(from: date))d"    }
        if hours(from: date)   > 0 { return "\(hours(from: date))h"   }
        if minutes(from: date) > 0 { return "\(minutes(from: date))m" }
        if seconds(from: date) > 0 { return "\(seconds(from: date))s" }
        return ""
    }
}

दिनांक घटक सूत्र का उपयोग करना

let dateComponentsFormatter = DateComponentsFormatter()
dateComponentsFormatter.allowedUnits = [.year,.month,.weekOfMonth,.day,.hour,.minute,.second]
dateComponentsFormatter.maximumUnitCount = 1
dateComponentsFormatter.unitsStyle = .full
dateComponentsFormatter.string(from: Date(), to: Date(timeIntervalSinceNow: 4000000))  // "1 month"

let date1 = DateComponents(calendar: .current, year: 2014, month: 11, day: 28, hour: 5, minute: 9).date!
let date2 = DateComponents(calendar: .current, year: 2015, month: 8, day: 28, hour: 5, minute: 9).date!

let years = date2.years(from: date1)     // 0
let months = date2.months(from: date1)   // 9
let weeks = date2.weeks(from: date1)     // 39
let days = date2.days(from: date1)       // 273
let hours = date2.hours(from: date1)     // 6,553
let minutes = date2.minutes(from: date1) // 393,180
let seconds = date2.seconds(from: date1) // 23,590,800

let timeOffset = date2.offset(from: date1) // "9M"

let date3 = DateComponents(calendar: .current, year: 2014, month: 11, day: 28, hour: 5, minute: 9).date!
let date4 = DateComponents(calendar: .current, year: 2015, month: 11, day: 28, hour: 5, minute: 9).date!

let timeOffset2 = date4.offset(from: date3) // "1y"

let date5 = DateComponents(calendar: .current, year: 2017, month: 4, day: 28).date!
let now = Date()
let timeOffset3 = now.offset(from: date5) // "1w"

1
स्विफ्ट 2.0 में, .CalendarUnitSecondत्रुटि देता है 'NSCalendarUnit.Type' does not have a member named 'CalendarUnitSecond', क्या आप जानते हैं कि इसे कैसे हल किया जाए?
मैट। कर जूल

2
@ Matte.Car आपको उपयोग करने की आवश्यकता है ।econd और विकल्पों के बजाय: nil आपको विकल्पों का उपयोग करने की आवश्यकता है: []। आप मेरे संपादन पर एक नज़र डाल सकते हैं।
लियो डबस

1
मुझे इस उत्तर में दोहराव से नफरत है, मैं इसके आधार पर एक विधि का उपयोग करूंगा NSCalendarUnit, जिसे लागू किया जाएगाreturn Calendar.current().components(unit, from: date, to: self, options: [])?. valueForComponent(unit) (iOS> 8 पर) के ।
सुल्तान

4
चूंकि उत्तर का उपयोग DateComponentsFormatterकरना SO इतना बेहतर है कि इसे लंबा करने से बेहतर है कि वास्तव में उत्तर के शीर्ष पर होना चाहिए।
रम्मदी

1
आप बिल्कुल अद्भुत हैं! इस एक्सटेंशन ने मुझे बहुत मदद की!
मैरिएन पेट्रीसर

45

अगर किसी को सभी समय इकाइयों को प्रदर्शित करने की आवश्यकता है जैसे "घंटे मिनट सेकंड" केवल "घंटे" नहीं। मान लीजिए कि दो तिथियों के बीच का समय अंतर 1 घंटे 59 मिनट 20 सेकंड है। यह फ़ंक्शन "1h 59m 20s" प्रदर्शित करेगा।

यहाँ मेरा उद्देश्य-सी कोड है:

extension NSDate {

    func offsetFrom(date: NSDate) -> String {

        let dayHourMinuteSecond: NSCalendarUnit = [.Day, .Hour, .Minute, .Second]
        let difference = NSCalendar.currentCalendar().components(dayHourMinuteSecond, fromDate: date, toDate: self, options: [])

        let seconds = "\(difference.second)s"
        let minutes = "\(difference.minute)m" + " " + seconds
        let hours = "\(difference.hour)h" + " " + minutes
        let days = "\(difference.day)d" + " " + hours

        if difference.day    > 0 { return days }
        if difference.hour   > 0 { return hours }
        if difference.minute > 0 { return minutes }
        if difference.second > 0 { return seconds }
        return ""
    }

}

स्विफ्ट 3+ में:

extension Date {

    func offsetFrom(date: Date) -> String {

        let dayHourMinuteSecond: Set<Calendar.Component> = [.day, .hour, .minute, .second]
        let difference = NSCalendar.current.dateComponents(dayHourMinuteSecond, from: date, to: self)

        let seconds = "\(difference.second ?? 0)s"
        let minutes = "\(difference.minute ?? 0)m" + " " + seconds
        let hours = "\(difference.hour ?? 0)h" + " " + minutes
        let days = "\(difference.day ?? 0)d" + " " + hours

        if let day = difference.day, day          > 0 { return days }
        if let hour = difference.hour, hour       > 0 { return hours }
        if let minute = difference.minute, minute > 0 { return minutes }
        if let second = difference.second, second > 0 { return seconds }
        return ""
    }

}

3
यह ठीक वैसा ही है जैसा मुझे चाहिए। सरल, और काम हो जाता है।
चेन ली योंग

14

तुम पूछो:

मैं एक ऐसा कार्य करना चाहता हूँ जो दो तिथियों की तुलना करता है और यदि (सेकंड> 60) तो मिनट लौटता है, यदि (मिनट> 60) घंटे लौटाता है और यदि (घंटे> 24) वापसी के दिन और इसी तरह।

मैं मान रहा हूं कि आप दो तिथियों के बीच बीता समय का एक स्ट्रिंग प्रतिनिधित्व बनाने की कोशिश कर रहे हैं। ऐसा करने के लिए अपना स्वयं का कोड लिखने के बजाय, Apple के पास पहले से ही ऐसा एक वर्ग है जिसे ठीक करने के लिए डिज़ाइन किया गया है। अर्थात्, उपयोग करें DateComponentsFormatter, allowedUnitsजो भी मूल्य आपके ऐप के लिए मायने रखता है, उसे सेट unitsStyleकरें जो आप चाहते हैं (जैसे .full), और फिर कॉल करें string(from:to:)

जैसे स्विफ्ट 3 में:

let previousDate = ...
let now = Date()

let formatter = DateComponentsFormatter()
formatter.unitsStyle = .full
formatter.allowedUnits = [.month, .day, .hour, .minute, .second]
formatter.maximumUnitCount = 2   // often, you don't care about seconds if the elapsed time is in months, so you'll set max unit to whatever is appropriate in your case

let string = formatter.string(from: previousDate, to: now)

यह प्रश्न में डिवाइस के लिए उपयुक्त स्ट्रिंग को भी स्थानीय करेगा।

या, स्विफ्ट 2.3 में:

let previousDate = ...
let now = NSDate()

let formatter = NSDateComponentsFormatter()
formatter.unitsStyle = .Full
formatter.allowedUnits = [.Month, .Day, .Hour, .Minute, .Second]
formatter.maximumUnitCount = 2

let string = formatter.stringFromDate(previousDate, toDate: now)

यदि आप वास्तविक संख्यात्मक मूल्यों की तलाश कर रहे हैं, तो बस उपयोग करें dateComponents। जैसे स्विफ्ट 3 में:

let components = Calendar.current.dateComponents([.month, .day, .hour, .minute, .second], from: previousDate, to: now)

या, स्विफ्ट 2.3 में:

let components = NSCalendar.currentCalendar().components([.Month, .Day, .Hour, .Minute, .Second], fromDate: previousDate, toDate: now, options: [])

6

संयुक्त एक्सटेंशन + DateCompordsFormatter @ leo-dabus के उत्तर से

Xcode 8.3 • स्विफ्ट 3.1

extension DateComponentsFormatter {
    func difference(from fromDate: Date, to toDate: Date) -> String? {
        self.allowedUnits = [.year,.month,.weekOfMonth,.day]
        self.maximumUnitCount = 1
        self.unitsStyle = .full
        return self.string(from: fromDate, to: toDate)
    }
}

let dateComponentsFormatter = DateComponentsFormatter()
dateComponentsFormatter.difference(from: Date(), to: Date(timeIntervalSinceNow: 4000000)) // "1 month"

4
   func dateDiff(dateStr:String) -> String {
            var f:NSDateFormatter = NSDateFormatter()
            f.timeZone = NSTimeZone.localTimeZone()
            f.dateFormat = "yyyy-M-dd'T'HH:mm:ss.SSSZZZ"

            var now = f.stringFromDate(NSDate())
            var startDate = f.dateFromString(dateStr)
            var endDate = f.dateFromString(now)
            var calendar: NSCalendar = NSCalendar.currentCalendar()

            let calendarUnits = NSCalendarUnit.CalendarUnitWeekOfMonth | NSCalendarUnit.CalendarUnitDay | NSCalendarUnit.CalendarUnitHour | NSCalendarUnit.CalendarUnitMinute | NSCalendarUnit.CalendarUnitSecond
            let dateComponents = calendar.components(calendarUnits, fromDate: startDate!, toDate: endDate!, options: nil)

            let weeks = abs(dateComponents.weekOfMonth)
            let days = abs(dateComponents.day)
            let hours = abs(dateComponents.hour)
            let min = abs(dateComponents.minute)
            let sec = abs(dateComponents.second)

            var timeAgo = ""

            if (sec > 0){
                if (sec > 1) {
                    timeAgo = "\(sec) Seconds Ago"
                } else {
                    timeAgo = "\(sec) Second Ago"
                }
            }

            if (min > 0){
                if (min > 1) {
                    timeAgo = "\(min) Minutes Ago"
                } else {
                    timeAgo = "\(min) Minute Ago"
                }
            }

            if(hours > 0){
                if (hours > 1) {
                    timeAgo = "\(hours) Hours Ago"
                } else {
                    timeAgo = "\(hours) Hour Ago"
                }
            }

            if (days > 0) {
                if (days > 1) {
                    timeAgo = "\(days) Days Ago"
                } else {
                    timeAgo = "\(days) Day Ago"
                }
            }

            if(weeks > 0){
                if (weeks > 1) {
                    timeAgo = "\(weeks) Weeks Ago"
                } else {
                    timeAgo = "\(weeks) Week Ago"
                }
            }

            print("timeAgo is===> \(timeAgo)")
            return timeAgo;
        }

आलसी को डेट फ़ॉर्मेटर लोड करने की कोशिश करें और बेहतर विकल्प भी इसे स्थिर बनाने के लिए होगा
thesummersign

4

मैंने लियो डबस के asnwer में एक "लंबा" संस्करण जोड़ा है यदि आप एक स्ट्रिंग चाहते हैं जो "2 सप्ताह पहले" के बजाय "2 सप्ताह पहले" जैसा कुछ कहे ...

extension Date {
    /// Returns the amount of years from another date
    func years(from date: Date) -> Int {
        return Calendar.current.dateComponents([.year], from: date, to: self).year ?? 0
    }
    /// Returns the amount of months from another date
    func months(from date: Date) -> Int {
        return Calendar.current.dateComponents([.month], from: date, to: self).month ?? 0
    }
    /// Returns the amount of weeks from another date
    func weeks(from date: Date) -> Int {
        return Calendar.current.dateComponents([.weekOfYear], from: date, to: self).weekOfYear ?? 0
    }
    /// Returns the amount of days from another date
    func days(from date: Date) -> Int {
        return Calendar.current.dateComponents([.day], from: date, to: self).day ?? 0
    }
    /// Returns the amount of hours from another date
    func hours(from date: Date) -> Int {
        return Calendar.current.dateComponents([.hour], from: date, to: self).hour ?? 0
    }
    /// Returns the amount of minutes from another date
    func minutes(from date: Date) -> Int {
        return Calendar.current.dateComponents([.minute], from: date, to: self).minute ?? 0
    }
    /// Returns the amount of seconds from another date
    func seconds(from date: Date) -> Int {
        return Calendar.current.dateComponents([.second], from: date, to: self).second ?? 0
    }
    /// Returns the a custom time interval description from another date
    func offset(from date: Date) -> String {
        if years(from: date)   > 0 { return "\(years(from: date))y"   }
        if months(from: date)  > 0 { return "\(months(from: date))M"  }
        if weeks(from: date)   > 0 { return "\(weeks(from: date))w"   }
        if days(from: date)    > 0 { return "\(days(from: date))d"    }
        if hours(from: date)   > 0 { return "\(hours(from: date))h"   }
        if minutes(from: date) > 0 { return "\(minutes(from: date))m" }
        if seconds(from: date) > 0 { return "\(seconds(from: date))s" }
        return ""
    }

    func offsetLong(from date: Date) -> String {
        if years(from: date)   > 0 { return years(from: date) > 1 ? "\(years(from: date)) years ago" : "\(years(from: date)) year ago" }
        if months(from: date)  > 0 { return months(from: date) > 1 ? "\(months(from: date)) months ago" : "\(months(from: date)) month ago" }
        if weeks(from: date)   > 0 { return weeks(from: date) > 1 ? "\(weeks(from: date)) weeks ago" : "\(weeks(from: date)) week ago"   }
        if days(from: date)    > 0 { return days(from: date) > 1 ? "\(days(from: date)) days ago" : "\(days(from: date)) day ago" }
        if hours(from: date)   > 0 { return hours(from: date) > 1 ? "\(hours(from: date)) hours ago" : "\(hours(from: date)) hour ago"   }
        if minutes(from: date) > 0 { return minutes(from: date) > 1 ? "\(minutes(from: date)) minutes ago" : "\(minutes(from: date)) minute ago" }
        if seconds(from: date) > 0 { return seconds(from: date) > 1 ? "\(seconds(from: date)) seconds ago" : "\(seconds(from: date)) second ago" }
        return ""
    }

}

4

-> स्विफ्ट (दो स्ट्रिंग्स के साथ) में दो तिथियों के बीच समय अंतराल ज्ञात करने के लिए इसका उपयोग करें ।

func timeGapBetweenDates(previousDate : String,currentDate : String)
{
    let dateString1 = previousDate
    let dateString2 = currentDate

    let Dateformatter = DateFormatter()
    Dateformatter.dateFormat = "yyyy-MM-dd HH:mm:ss"


    let date1 = Dateformatter.date(from: dateString1)
    let date2 = Dateformatter.date(from: dateString2)


    let distanceBetweenDates: TimeInterval? = date2?.timeIntervalSince(date1!)
    let secondsInAnHour: Double = 3600
    let minsInAnHour: Double = 60
    let secondsInDays: Double = 86400
    let secondsInWeek: Double = 604800
    let secondsInMonths : Double = 2592000
    let secondsInYears : Double = 31104000

    let minBetweenDates = Int((distanceBetweenDates! / minsInAnHour))
    let hoursBetweenDates = Int((distanceBetweenDates! / secondsInAnHour))
    let daysBetweenDates = Int((distanceBetweenDates! / secondsInDays))
    let weekBetweenDates = Int((distanceBetweenDates! / secondsInWeek))
    let monthsbetweenDates = Int((distanceBetweenDates! / secondsInMonths))
    let yearbetweenDates = Int((distanceBetweenDates! / secondsInYears))
    let secbetweenDates = Int(distanceBetweenDates!)




    if yearbetweenDates > 0
    {
        print(yearbetweenDates,"years")//0 years
    }
    else if monthsbetweenDates > 0
    {
        print(monthsbetweenDates,"months")//0 months
    }
    else if weekBetweenDates > 0
    {
        print(weekBetweenDates,"weeks")//0 weeks
    }
    else if daysBetweenDates > 0
    {
        print(daysBetweenDates,"days")//5 days
    }
    else if hoursBetweenDates > 0
    {
        print(hoursBetweenDates,"hours")//120 hours
    }
    else if minBetweenDates > 0
    {
        print(minBetweenDates,"minutes")//7200 minutes
    }
    else if secbetweenDates > 0
    {
        print(secbetweenDates,"seconds")//seconds
    }
}

3

स्विफ्ट 3.0 के लिए थोड़ा संशोधित कोड

let calendar = NSCalendar.current as NSCalendar

// Replace the hour (time) of both dates with 00:00
let date1 = calendar.startOfDay(for: startDateTime)
let date2 = calendar.startOfDay(for: endDateTime)

let flags = NSCalendar.Unit.day
let components = calendar.components(flags, from: date1, to: date2, options: [])

return components.day!

3

स्विफ्ट 5.1 • आईओएस 13

आप RelativeDateFormatter का उपयोग कर सकते हैं जो Apple द्वारा iOS 13 में पेश किया गया है।

let exampleDate = Date().addingTimeInterval(-15000)

let formatter = RelativeDateTimeFormatter()
formatter.unitsStyle = .full
let relativeDate = formatter.localizedString(for: exampleDate, relativeTo: Date())

print(relativeDate) // 4 hours ago

RelativeDateTimeFormatter का उपयोग करके एक सापेक्ष दिनांक और समय दिखाने का तरीका देखें ।


1

यदि आपका उद्देश्य दो तिथियों के बीच सटीक दिन संख्या प्राप्त करना है, तो आप इस तरह से इस मुद्दे पर काम कर सकते हैं:

// Assuming that firstDate and secondDate are defined
// ...

var calendar: NSCalendar = NSCalendar.currentCalendar()

// Replace the hour (time) of both dates with 00:00
let date1 = calendar.startOfDayForDate(firstDate)
let date2 = calendar.startOfDayForDate(secondDate)

let flags = NSCalendarUnit.DayCalendarUnit
let components = calendar.components(flags, fromDate: date1, toDate: date2, options: nil)

components.day  // This will return the number of day(s) between dates

1

स्विफ्ट 3 के साथ, अपनी आवश्यकताओं के अनुसार, आप अपनी समस्या को हल करने के लिए निम्नलिखित दो तरीकों में से एक चुन सकते हैं।


1. उपयोगकर्ता को दो तिथियों के बीच का अंतर प्रदर्शित करें

आप DateComponentsFormatterअपने ऐप के इंटरफ़ेस के लिए स्ट्रिंग्स बनाने के लिए उपयोग कर सकते हैं । निम्नलिखित घोषणा के साथ DateComponentsFormatterएक maximumUnitCountसंपत्ति है:

var maximumUnitCount: Int { get set }

परिणामी स्ट्रिंग में प्रदर्शित इकाइयों की संख्या को सीमित करने के लिए इस संपत्ति का उपयोग करें। उदाहरण के लिए, इस संपत्ति के साथ "1h 10m, 30s" के बजाय 2 सेट करें, जिसके परिणामस्वरूप स्ट्रिंग "1h 10m" होगी। जब आप अंतरिक्ष के लिए विवश हों तो इस संपत्ति का उपयोग करें या निकटतम बड़ी इकाई के लिए मूल्यों को गोल करना चाहते हैं।

का maximumUnitCountमान सेट करके 1, आपको केवल एक में अंतर प्रदर्शित करने की गारंटी हैDateComponentsFormatter इकाई (वर्ष, महीने, दिन, घंटे या मिनट) ।

नीचे दिया गया खेल का मैदान कोड दिखाता है कि दो तिथियों के बीच का अंतर कैसे दिखाया जाए:

import Foundation

let oldDate = Date(timeIntervalSinceReferenceDate: -16200)
let newDate = Date(timeIntervalSinceReferenceDate: 0)

let dateComponentsFormatter = DateComponentsFormatter()
dateComponentsFormatter.allowedUnits = [NSCalendar.Unit.year, .month, .day, .hour, .minute]
dateComponentsFormatter.maximumUnitCount = 1
dateComponentsFormatter.unitsStyle = DateComponentsFormatter.UnitsStyle.full
let timeDifference = dateComponentsFormatter.string(from: oldDate, to: newDate)

print(String(reflecting: timeDifference)) // prints Optional("5 hours")

ध्यान दें कि DateComponentsFormatterपरिणाम गोल है। इसलिए, 4 घंटे और 30 मिनट का अंतर 5 घंटे के रूप में प्रदर्शित किया जाएगा

यदि आपको इस ऑपरेशन को दोहराने की आवश्यकता है, तो आप अपने कोड को रिफलेक्टर कर सकते हैं:

import Foundation

struct Formatters {

    static let dateComponentsFormatter: DateComponentsFormatter = {
        let dateComponentsFormatter = DateComponentsFormatter()
        dateComponentsFormatter.allowedUnits = [NSCalendar.Unit.year, .month, .day, .hour, .minute]
        dateComponentsFormatter.maximumUnitCount = 1
        dateComponentsFormatter.unitsStyle = DateComponentsFormatter.UnitsStyle.full
        return dateComponentsFormatter
    }()

}

extension Date {
    
    func offset(from: Date) -> String? {
        return Formatters.dateComponentsFormatter.string(from: oldDate, to: self)
    }
    
}

let oldDate = Date(timeIntervalSinceReferenceDate: -16200)
let newDate = Date(timeIntervalSinceReferenceDate: 0)

let timeDifference = newDate.offset(from: oldDate)
print(String(reflecting: timeDifference)) // prints Optional("5 hours")

2. प्रारूपण के बिना दो तिथियों के बीच अंतर प्राप्त करें

यदि आपको उपयोगकर्ता को दो तिथियों के बीच अंतर को प्रारूपित करने की आवश्यकता नहीं है, तो आप उपयोग कर सकते हैं CalendarCalendarएक विधि dateComponents(_:from:to:)है जिसमें निम्नलिखित घोषणा है:

func dateComponents(_ components: Set<Calendar.Component>, from start: Date, to end: Date) -> DateComponents

दो तिथियों के बीच का अंतर लौटाता है।

नीचे दिए गए प्लेग्राउंड कोड से dateComponents(_:from:to:)पता चलता है कि केवल एक प्रकार Calendar.Component(वर्ष, महीने, दिन, घंटे या मिनट) में अंतर वापस करके दो तिथियों के बीच अंतर कैसे प्राप्त किया जा सकता है ।

import Foundation

let oldDate = Date(timeIntervalSinceReferenceDate: -16200)
let newDate = Date(timeIntervalSinceReferenceDate: 0)

let descendingOrderedComponents = [Calendar.Component.year, .month, .day, .hour, .minute]
let dateComponents = Calendar.current.dateComponents(Set(descendingOrderedComponents), from: oldDate, to: newDate)
let arrayOfTuples = descendingOrderedComponents.map { ($0, dateComponents.value(for: $0)) }

for (component, value) in arrayOfTuples {
    if let value = value, value > 0 {
        print(component, value) // prints hour 4
        break
    }
}

यदि आपको इस ऑपरेशन को दोहराने की आवश्यकता है, तो आप अपने कोड को रिफलेक्टर कर सकते हैं:

import Foundation

extension Date {
    
    func offset(from: Date) -> (Calendar.Component, Int)? {
        let descendingOrderedComponents = [Calendar.Component.year, .month, .day, .hour, .minute]
        let dateComponents = Calendar.current.dateComponents(Set(descendingOrderedComponents), from: from, to: self)
        let arrayOfTuples = descendingOrderedComponents.map { ($0, dateComponents.value(for: $0)) }
        
        for (component, value) in arrayOfTuples {
            if let value = value, value > 0 {
                return (component, value)
            }
        }
        
        return nil
    }

}

let oldDate = Date(timeIntervalSinceReferenceDate: -16200)
let newDate = Date(timeIntervalSinceReferenceDate: 0)

if let (component, value) = newDate.offset(from: oldDate) {
    print(component, value) // prints hour 4
}

1

स्विफ्ट में 2.2

    /// Returns the amount of years from another date
func years(fromdate: NSDate) -> Int {
    return NSCalendar.currentCalendar().components([.Year], fromDate: fromdate, toDate: NSDate(), options: []).year ?? 0
}
/// Returns the amount of months from another date
func months(fromdate: NSDate) -> Int {
    return NSCalendar.currentCalendar().components([.Month], fromDate: fromdate, toDate: NSDate(), options: []).month ?? 0
}
/// Returns the amount of weeks from another date
func weeks(fromdate: NSDate) -> Int {
    return NSCalendar.currentCalendar().components([.WeekOfYear], fromDate: fromdate, toDate: NSDate(), options: []).weekOfYear ?? 0
}
/// Returns the amount of days from another date
func days(fromdate: NSDate) -> Int {
    return NSCalendar.currentCalendar().components([.Day], fromDate: fromdate, toDate: NSDate(), options: []).day ?? 0
}
/// Returns the amount of hours from another date
func hours(fromdate: NSDate) -> Int {
    return NSCalendar.currentCalendar().components([.Hour], fromDate: fromdate, toDate: NSDate(), options: []).hour ?? 0
}
/// Returns the amount of minutes from another date
func minutes(fromdate: NSDate) -> Int {
    return NSCalendar.currentCalendar().components([.Minute], fromDate: fromdate, toDate: NSDate(), options: []).minute ?? 0
}
/// Returns the amount of seconds from another date
func seconds(fromdate: NSDate) -> Int {
    return NSCalendar.currentCalendar().components(.Second, fromDate: fromdate, toDate: NSDate(), options: []).second ?? 0
}

1

बहुवचन संस्करण प्रदान करने और अधिक मानवीय पठनीय होने के लिए लियो डबस का एक छोटा सा उत्तर।

स्विफ्ट 3

extension Date {
    /// Returns the amount of years from another date
    func years(from date: Date) -> Int {
        return Calendar.current.dateComponents([.year], from: date, to: self).year ?? 0
    }
    /// Returns the amount of months from another date
    func months(from date: Date) -> Int {
        return Calendar.current.dateComponents([.month], from: date, to: self).month ?? 0
    }
    /// Returns the amount of weeks from another date
    func weeks(from date: Date) -> Int {
        return Calendar.current.dateComponents([.weekOfMonth], from: date, to: self).weekOfMonth ?? 0
    }
    /// Returns the amount of days from another date
    func days(from date: Date) -> Int {
        return Calendar.current.dateComponents([.day], from: date, to: self).day ?? 0
    }
    /// Returns the amount of hours from another date
    func hours(from date: Date) -> Int {
        return Calendar.current.dateComponents([.hour], from: date, to: self).hour ?? 0
    }
    /// Returns the amount of minutes from another date
    func minutes(from date: Date) -> Int {
        return Calendar.current.dateComponents([.minute], from: date, to: self).minute ?? 0
    }
    /// Returns the amount of seconds from another date
    func seconds(from date: Date) -> Int {
        return Calendar.current.dateComponents([.second], from: date, to: self).second ?? 0
    }
    /// Returns the a custom time interval description from another date
    func offset(from date: Date) -> String {
        if years(from: date)   == 1 { return "\(years(from: date)) year"   } else if years(from: date)   > 1 { return "\(years(from: date)) years"   }
        if months(from: date)  == 1 { return "\(months(from: date)) month"  } else if months(from: date)  > 1 { return "\(months(from: date)) month"  }
        if weeks(from: date)   == 1 { return "\(weeks(from: date)) week"   } else if weeks(from: date)   > 1 { return "\(weeks(from: date)) weeks"   }
        if days(from: date)    == 1 { return "\(days(from: date)) day"    } else if days(from: date)    > 1 { return "\(days(from: date)) days"    }
        if hours(from: date)   == 1 { return "\(hours(from: date)) hour"   } else if hours(from: date)   > 1 { return "\(hours(from: date)) hours"   }
        if minutes(from: date) == 1 { return "\(minutes(from: date)) minute" } else if minutes(from: date) > 1 { return "\(minutes(from: date)) minutes" }
        return ""
    }
}

0

यह छोटा संस्करण है: मूल रूप से मैं Date()अब के साथ पोस्ट टाइमस्टैम्प के बीच अंतर प्राप्त करने की कोशिश करता हूं ।

// MARK: - UPDATE Time Stamp
static func updateTimeStampPost(postTimeStamp: Date?, _ completion: (_ finalString: String?) -> Void) {
    // date in the current state
    let date = Date()
    let dateComponentFormatter = DateComponentsFormatter()

    // change the styling date, wether second minute or hour
    dateComponentFormatter.unitsStyle = .abbreviated
    dateComponentFormatter.allowedUnits = [.second, .minute, .hour, .day, .weekOfMonth]
    dateComponentFormatter.maximumUnitCount = 1

    // return the date new format as a string in the completion
    completion(dateComponentFormatter.string(from: postTimeStamp!, to: date))
}

0

ऊपर दिए गए स्विफ्ट 3 उत्तरों के लिए यहां मेरा जवाब है। यह नवंबर 2016 तक चालू है, Xcode रिलीज़ 8.2 बीटा (8C23) था। ऊपर सागर और एमिन दोनों सुझावों में से कुछ का इस्तेमाल किया और कभी-कभी सिंटैक्स का सुझाव देने के लिए एक्सकोड को स्वत: पूर्ण होने देना पड़ा। ऐसा लग रहा था कि वाक्य विन्यास वास्तव में इस बीटा संस्करण में बदल गया है। buyDateमैं एक DatePicker से मिला:

let calendar = NSCalendar.current as NSCalendar
let currentDate = Date()
let date1 = calendar.startOfDay(for: buyDate!)
let date2 = calendar.startOfDay(for: currentDate)      
let flags = NSCalendar.Unit.day
let components = calendar.components(flags, from: date1, to: date2)
NSLog(" day= \(components.day)")

क्षमा करें, अब जब मैं इसे देखता हूं, तो यह सागर का समाधान है। मैंने बहुत सारे पुनरावृत्तियां कीं और बहुत सारी चीजों की कोशिश की, मुझे लगा कि यह बदल गया है। एमिन का समाधान नवीनतम स्विफ्ट 3 के लिए काम नहीं करता है
पुनर्जागरण

आप वास्तव NSCalendarमें स्विफ्ट 3 में उपयोग नहीं करना चाहिए । उपयोग करें Calendar। तो यह सरल है let calendar = Calendar.current। और फिर componentsऐसा दिखेगा let components = calendar.dateComponents([.day], from: date1, to: date2):।
रोब

0

XCode संस्करण 8.3.3 और स्विफ्ट 3.0 के लिए:

    let dateFormatter = DateFormatter()
    dateFormatter.dateStyle = .medium
    dateFormatter.timeStyle = .short

    var beginDate = "2017-08-24 12:00:00"
    var endDate = "2017-09-07 12:00:00"


    let startDateTime = dateFormatter.date(from: beginDate) //according to date format your date string
    print(startDateTime ?? "") //Convert String to Date

    let endDateTime = dateFormatter.date(from: endDate) //according to date format your date string
    print(endDateTime ?? "") //Convert String to Date

    let dateComponentsFormatter = DateComponentsFormatter()
    dateComponentsFormatter.allowedUnits = [NSCalendar.Unit.minute,NSCalendar.Unit.hour,NSCalendar.Unit.day]


   let interval = endDateTime!.timeIntervalSince(startDateTime!)
   var diff = dateComponentsFormatter.string(from: interval)!

   print(diff)

   var day_i  = 0
   var hour_i = 0
   var min_i = 0


     if (diff.contains("d"))
       {
              let day = diff.substring(to: (diff.range(of: "d")?.lowerBound)!)

               day_i  = Int(day)!
               print ("day --> \(day_i)")

               diff = diff.substring(from:(diff.range(of : " ")?.upperBound )!)
               print(diff)
       }


       let hour = diff.substring(to: (diff.range(of : ":")?.lowerBound )!)
       hour_i  = Int(hour)!
       print ("hour --> \(hour_i)")

       let min = diff.substring(from: (diff.range(of : ":")?.upperBound )!)
       min_i  = Int(min)!
       print ("min --> \(min_i)")

0

Jose920405 में कुछ जोड़ इसे स्विफ्ट 3.0 और इसके बाद के संस्करण के साथ संगत करने के लिए उत्तर देते हैं

func getDateTimeDiff(dateStr:String) -> String {

    let formatter : DateFormatter = DateFormatter()
    formatter.timeZone = NSTimeZone.local
    formatter.dateFormat = "yyyy-MM-dd HH:mm:ss"

    let now = formatter.string(from: NSDate() as Date)
    let startDate = formatter.date(from: dateStr)
    let endDate = formatter.date(from: now)

    // *** create calendar object ***
    var calendar = NSCalendar.current

    // *** Get components using current Local & Timezone ***
    print(calendar.dateComponents([.year, .month, .day, .hour, .minute, .second], from: startDate!))

    // *** define calendar components to use as well Timezone to UTC ***
    let unitFlags = Set<Calendar.Component>([.year, .month, .day, .hour, .minute, .second])
    calendar.timeZone = TimeZone(identifier: "UTC")!
    let dateComponents = calendar.dateComponents(unitFlags, from: startDate!, to: endDate!)

    // *** Get Individual components from date ***
    let years = dateComponents.year!
    let months = dateComponents.month!
    let days = dateComponents.day!
    let hours = dateComponents.hour!
    let minutes = dateComponents.minute!
    let seconds = dateComponents.second!

    var timeAgo = ""

    if (seconds > 0){
        if seconds < 2 {
            timeAgo = "Second Ago"
        }
        else{
            timeAgo = "\(seconds) Second Ago"
        }
    }

    if (minutes > 0){
        if minutes < 2 {
            timeAgo = "Minute Ago"
        }
        else{
            timeAgo = "\(minutes) Minutes Ago"
        }
    }

    if(hours > 0){
        if minutes < 2 {
            timeAgo = "Hour Ago"
        }
        else{
            timeAgo = "\(hours) Hours Ago"
        }
    }

    if (days > 0) {
        if minutes < 2 {
            timeAgo = "Day Ago"
        }
        else{
            timeAgo = "\(days) Days Ago"
        }
    }

    if(months > 0){
        if minutes < 2 {
            timeAgo = "Month Ago"
        }
        else{
            timeAgo = "\(months) Months Ago"
        }
    }

    if(years > 0){
        if minutes < 2 {
            timeAgo = "Year Ago"
        }
        else{
            timeAgo = "\(years) Years Ago"
        }
    }

    DLog("timeAgo is ===> \(timeAgo)")
    return timeAgo;
}

0

इस कोड का उपयोग करें:

let registrationDateString = "2008-10-06 00:00:00"
    let dateFormatter = DateFormatter()
    dateFormatter.dateFormat = "yyyy-MM-dd hh:mm:ss"
    if let registrationDate = dateFormatter.date(from: registrationDateString) {
        let currentDate = Date()
        let dateDifference = Calendar.current.dateComponents([.day, .month, .year],
                                                               from: registrationDate,
                                                               to: currentDate)
        print("--------------------- Result: \(dateDifference.year ?? 0) years \(dateDifference.month ?? 0) months and \(dateDifference.day ?? 0) days")
    } else {
        print("--------------------- No result")
    }

आउटपुट है: परिणाम: 10 साल 1 महीने और 18 दिन


0
import Foundation

extension DateComponents {

    func dateComponentsToTimeString() -> String {

        var hour = "\(self.hour!)"
        var minute = "\(self.minute!)"
        var second = "\(self.second!)"

        if self.hour! < 10 { hour = "0" + hour }
        if self.minute! < 10 { minute = "0" + minute }
        if self.second! < 10 { second = "0" + second }

        let str = "\(hour):\(minute):\(second)"
        return str
    }

}

extension Date {

    func offset(from date: Date)-> DateComponents {
        let components = Set<Calendar.Component>([.second, .minute, .hour, .day, .month, .year])
        let differenceOfDate = Calendar.current.dateComponents(components, from: date, to: self)
        return differenceOfDate
    }
}

उपयोग:

var durationString: String {
        return self.endTime.offset(from: self.startTime).dateComponentsToTimeString()
    }
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.