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

我该怎么做呢?

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


当前回答

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

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

以下是我对上述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的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 ""
    }
}

结合扩展+ 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"