如何比较两个日期组件

How to compare two date components

我正在开发像社交媒体应用这样的应用,用户 post 墙上的东西 post 数据保存到服务器,return 保存到应用我想获得 post 喜欢 facebook Instagram 等(5 小时前) 我从服务器得到的响应是

“2020-03-07T13:15:09”

所以首先我从我的日期时间中拆分毫秒

func date(post: mdlSocialFeedbackView.mdlMemberWallPost) -> String{
    let timeDateWithoutMilliseconds = post.CreatedDate!.split(separator: ".")[0]
    let date = timeDateWithoutMilliseconds.split(separator: "T")[0]
    let time = timeDateWithoutMilliseconds.split(separator: "T")[1]
    let formatter = DateFormatter()
    let timeDateObject = formatter.timeFromServer(time: String(time))
    let dateObject = formatter.dateFromServer(date: String(date))
    let calender = Calendar.current
    let dateString = calender.dateOfPostOnWall(dateTime: dateObject!)
    if let date = dateString{
        return date
    }else{
        let timeString = calender.timeOfPostOnWall(dateTime: timeDateObject!)
        return timeString!
    }
}

我在我的 UIViewController class 中使用这个函数从服务器获取时间和 return post 的确切时间。 Calender 和 DateFormatter classes 中的扩展,还帮助我并指导我格式化当前时区

extension DateFormatter{

func dateFromServer(date: String) -> Date?{
    let formatter = DateFormatter()
    formatter.dateFormat = "yyyy-MM-dd"
    //formatter.timeZone = TimeZone(secondsFromGMT: 0)
    formatter.timeZone = .current
    return formatter.date(from: date)
}

func timeFromServer(time: String) -> Date?{
    let formatter = DateFormatter()
    formatter.dateFormat = "HH:mm:ss"
    //formatter.timeZone = TimeZone(secondsFromGMT: 0)
    formatter.timeZone = .current
    return formatter.date(from: time)
}

}

extension Calendar{

func timeOfPostOnWall(dateTime: Date?)-> String?{
    let componentOfTime = self.dateComponents([.hour, .minute, .second], from: dateTime!)
    let componentOfCurrentTime = self.dateComponents([.hour, .minute,.second], from: Date())
    guard componentOfCurrentTime.hour ==  componentOfTime.hour
        else{
            return "about \(componentOfCurrentTime.hour! - componentOfTime.hour!) hours ago."}
    guard componentOfCurrentTime.minute  == componentOfTime.minute
        else{
            return "about \(componentOfCurrentTime.minute! - componentOfTime.minute!) minutes ago."
    }
    guard componentOfCurrentTime.second == componentOfTime.second
        else{
        return "about \(componentOfCurrentTime.second! - componentOfTime.second!) seconds ago."
    }
    return nil
}

func dateOfPostOnWall(dateTime: Date?)-> String?{
    let componentOfTime = self.dateComponents([.year, .month, .day], from: dateTime!)
    let componentOfCurrentTime = self.dateComponents([.year, .month, .day], from: Date())
    guard componentOfCurrentTime.year ==  componentOfTime.year
        else{
            return "about \(componentOfCurrentTime.year! - componentOfTime.year!) years ago."}
    guard componentOfCurrentTime.month ==  componentOfTime.month
        else{
            return "about \(componentOfCurrentTime.month! - componentOfTime.month!) months ago."
    }
    guard componentOfCurrentTime.day == componentOfTime.day
        else{
        return "about \(componentOfCurrentTime.day! - componentOfTime.day!) days ago."
    }
    return nil
}  

}

现在的问题是什么时候我 post 当前时间的某些组成部分 return enter image description here 和墙上的回应是这样的

enter image description here

你的约会对象是 ISO 8601. So use an ISO8601DateFormatter

final class ISO8601DateFormatter: Foundation.ISO8601DateFormatter {
  override init() {
    super.init()
    formatOptions.remove(.withTimeZone)
  }

  required init?(coder: NSCoder) {
    super.init(coder: coder)
  }
}

ISO8601DateFormatter().date(from: "2020-03-07T13:15:09")

这个错误的原因似乎是您的服务器时钟与设备时间不同步。你应该找出哪个时钟有 "correct" 时间并调整另一个时钟。或者,重写服务器端代码以根据服务器时钟响应当前时间。

无论如何,您也在重新发明代码中的轮子很多。该错误也可能是由您自己编写的日期和时间处理代码引起的。您应该改用内置 API,因为它们出现错误的可能性较小。

您收到的日期采用 ISO 8601 格式,因此您可以使用 ISO8601DateFormatter 对其进行解析。您的 dateFromServertimeFromServer 方法非常多余。

func date(post: mdlSocialFeedbackView.mdlMemberWallPost) -> String{
    let dateString = post.CreatedDate!
    let formatter = ISO8601DateFormatter()
    formatter.formatOptions = [.withColonSeparatorInTime, .withTime, .withFullDate]
    let date = formatter.date(from: dateString)

    // to be continued
}

您查找两个日期之间差异的方法至少可以说是有问题的。如果我在 12 月 31 日 post 某些东西,并在 1 月 1 日查看它,我会看到 "about 1 year ago",我个人预计 "about 1 day ago",或更少。

可以使用dateComponents(_:from:to:)方法:

// Calendar extension
func estimatedTimeFromNow(date: Date)-> String {
    let diff = self.dateComponents([.year, .month, day, .hour, .minute, .second], from: date, to: Date())
    if let year = diff.year {
        return "about \(year) year(s) ago"
    } else if let month = diff.month {
        return "about \(month) month(s) ago"
    } else if let day = diff.day {
        return "about \(day) day(s) ago"
    } else if let hour = diff.hour {
        return "about \(hour) hour(s) ago"
    } else if let minute = diff.minute {
        return "about \(minute) minute(s) ago"
    } else if let second = diff.second {
        return "about \(second) second(s) ago"
    } else {
        return "just now"
    }
}

date(post:)中:

return Calendar.current.estimatedTimeFromNow(date: date)