在Swift中获取两个日期(月/天/小时/分/秒)之间的差异

我正在尝试获得当前日期为NSDate()和来自PHP time();调用的日期之间的差异,例如:NSDate(timeIntervalSinceReferenceDate: 1417147270)。我怎样才能得到这两个日期之间的时间差呢?我想有一个函数,比较两个日期和if(seconds > 60),然后它返回分钟,if(minutes > 60)返回小时和if(hours > 24)返回日等。

我该怎么做呢?

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

148845 次浏览

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"

如果你的目的是获得两个日期之间的确切天数,你可以这样解决这个问题:

// 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
  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;
}

如果有人需要显示所有的时间单位,如“小时分秒”,而不仅仅是“小时”。假设两个日期的时差是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 ""
}


}

轻微修改了斯威夫特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!

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

你问:

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

我加了一个“long”;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 ""
}
}

使用Swift 3,根据您的需要,您可以选择以下两种方式之一来解决您的问题。


1. 向用户显示两个日期之间的差异

你可以使用DateComponentsFormatter为你的应用程序界面创建字符串。DateComponentsFormatter有一个maximumUnitCount属性,声明如下:

var maximumUnitCount: Int { get set }

使用此属性可限制结果字符串中显示的单位数量。例如,将此属性设置为2,而不是“1h 10m, 30s”,生成的字符串将是“1h 10m”。当空间受限或希望将值舍入到最近的大单位时,请使用此属性。

通过将maximumUnitCount的值设置为1,可以保证只显示一个DateComponentsFormatter的单位(年、月、日、小时或分钟)的差值。

下面的Playground代码显示了如何显示两个日期之间的差异:

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 hours and 30 minutes的差值将显示为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:)的Playground代码展示了如何通过返回仅一种类型的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
}

这是较短的版本:基本上,我现在试图获得发布时间戳与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))
}

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

结合扩展+ DateComponentsFormatter从@leo-dabus的答案

Xcode 8.3•Swift 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"

For XCode Version 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)")

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

jose920405 answer中的一些添加使其与斯威夫特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;
}

使用以下代码:

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天

使用此函数查找斯威夫特中两个日期之间的时间间隔(带有两个字符串)。

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
}
}
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()
}

Swift 5.1•iOS 13

你可以使用苹果在iOS 13中引入的RelativeDateFormatter

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

斯威夫特5

func dateDiff(dateStr:String) -> String {
let f:DateFormatter = DateFormatter()
f.timeZone = NSTimeZone.local
f.dateFormat = "yyyy-M-dd'T'HH:mm:ss.SSSZZZ"
      

let now = f.string(from: NSDate() as Date)
let startDate = f.date(from: dateStr)
let endDate = f.date(from: now)
var _: NSCalendar = NSCalendar.current as NSCalendar
      

    

let dateComponents = Calendar.current.dateComponents([ .weekOfMonth, .day , .hour , .minute , .second], from: startDate!, to: endDate!)
      

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