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

我该怎么做呢?

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


当前回答

以下是我对上述Swift 3的回答。这是截至2016年11月,Xcode发布版本为8.2 Beta (8C23)。使用上述Sagar和Emin的一些建议,有时不得不让Xcode自动完成来建议语法。在这个测试版中,语法似乎真的发生了变化。我从一个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)")

其他回答

Leo Dabus回答的一个小补充,提供复数版本,更易于人类阅读。

斯威夫特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 ""
    }
}

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

使用以下代码:

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天

你问:

我想有一个函数,比较两个日期,如果(秒> 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: [])

这是一个较短的版本:基本上我现在尝试获得post时间戳与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))
}