我试图得到当前日期之间的差异作为NSDate()和日期从一个PHP时间();调用例如:NSDate(timeintervalsincerely eferencedate: 1417147270)。我怎样才能得到这两个日期之间的时间差呢?我想有一个函数,比较两个日期,如果(秒> 60),那么它返回分钟,如果(分钟> 60)返回小时,如果(小时> 24)返回天,等等。

我该怎么做呢?

编辑:目前接受的答案完全符合我的想法。为了便于使用,我推荐使用它,以便以PHP time()函数使用的形式获取两个日期之间的时间。如果你不是特别熟悉PHP,这是1970年1月1日的时间,单位是秒。这对于PHP的后端是有益的。如果你正在使用像NodeJS这样的后端,你可能会考虑下面的其他选项。


当前回答

在jose920405中添加了一些答案,使其与Swift 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 hours < 2 {
            timeAgo = "Hour Ago"
        }
        else{
            timeAgo = "\(hours) Hours Ago"
        }
    }
    
    if (days > 0) {
        if days < 2 {
            timeAgo = "Day Ago"
        }
        else{
            timeAgo = "\(days) Days Ago"
        }
    }
    
    if(months > 0){
        if months < 2 {
            timeAgo = "Month Ago"
        }
        else{
            timeAgo = "\(months) Months Ago"
        }
    }
    
    if(years > 0){
        if years < 2 {
            timeAgo = "Year Ago"
        }
        else{
            timeAgo = "\(years) Years Ago"
        }
    }
    
    DLog("timeAgo is ===> \(timeAgo)")
    return timeAgo;
}

其他回答

我在Leo Dabus的asnwer中添加了一个“长”版本,以防你想要一个字符串,说“2周前”而不是“2w”……

extension Date {
    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 ""
    }
}

Xcode 8.3•Swift 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 = [.second, .minute, .hour, .day, .weekOfMonth, .month, .year]
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小时59分20秒。该功能将显示“1h 59m 20s”。

下面是我的Objective-C代码:

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 ""
    }

}

在Swift 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 ""
    }

}

你问:

我想有一个函数,比较两个日期,如果(秒> 60),那么它返回分钟,如果(分钟> 60)返回小时,如果(小时> 24)返回天,等等。

我假设您正在尝试构建两个日期之间经过时间的字符串表示。而不是自己写代码来做这件事,苹果已经有了一个专门设计来做这件事的类。也就是说,使用DateComponentsFormatter,将allowedUnits设置为对你的应用有意义的任何值,将unitsStyle设置为你想要的任何值(例如.full),然后调用string(from:to:)。

例如,在Swift 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)

这也将本地化对应于相关设备的字符串。

或者,在Swift 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。例如,在Swift 3中:

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

或者,在Swift 2.3中:

let components = NSCalendar.currentCalendar().components([.Month, .Day, .Hour, .Minute, .Second], fromDate: previousDate, toDate: now, options: [])
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
    }
}

Use:

var durationString: String {
        return self.endTime.offset(from: self.startTime).dateComponentsToTimeString()
    }