简体   繁体   English

如何比较两个日期组件

[英]How to compare two date components

I'm working on app like social media app where user post something on wall post data saved to server and return to app I want to get time of post like facebook Instagram etc.(5 hours ago) the response I get from server is我正在开发类似社交媒体应用程序的应用程序,其中用户在保存到服务器的墙上发布数据并返回应用程序我想获得像 facebook Instagram 等发布的时间(5 小时前)我从服务器得到的响应是

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

so first I split miliseconds from my datetime所以首先我从我的日期时间分割毫秒

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

I'm using this function in my UIViewController class to get time from server and return the exact time of post.我在 UIViewController 类中使用此函数从服务器获取时间并返回发布的确切时间。 Extentions in Calender and DateFormatter classes and also Help me and guide me to format the current time zone Calender 和 DateFormatter 类中的扩展以及帮助我​​和指导我格式化当前时区

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
}  

} }

now the issue is when ever I post something components of current time return enter image description here and response on wall something like this现在的问题是,当我发布当前时间的某些组件时,请在此处输入图像描述并在墙上响应类似这样的内容

enter image description here在此处输入图片说明

Your date is in ISO 8601 .您的日期在ISO 8601 中 So use an ISO8601DateFormatter !所以使用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")

The cause of this bug seems to be that your server clock is out of sync with the device's time.此错误的原因似乎是您的服务器时钟与设备时间不同步。 You should find out which clock has the "correct" time and adjust the other clock.您应该找出哪个时钟具有“正确”的时间并调整另一个时钟。 Alternatively, rewrite the server side code to respond with the current time according to the server's clock.或者,根据服务器的时钟重写服务器端代码以响应当前时间。

Anyway, you are also reinventing the wheel a lot in your code.无论如何,你也重新发明轮子了很多在你的代码。 The bug could also be caused by the date-and-time handling code you've written yourself.该错误也可能是由您自己编写的日期和时间处理代码引起的。 You should instead use the built-in APIs, because they are less likely to have bugs.您应该改用内置 API,因为它们不太可能出现错误。

The date you receive is in ISO 8601 format, so you can parse it with a ISO8601DateFormatter .您收到的日期采用 ISO 8601 格式,因此您可以使用ISO8601DateFormatter对其进行解析。 Your dateFromServer and timeFromServer methods are quite redundant.您的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
}

Your way of finding the difference between two dates is questionable to say the least.至少可以说,您找到两个日期之间差异的方法是有问题的。 If I post something on December 31, and I view it on January 1, I would see "about 1 year ago", where I personally would expect "about 1 day ago", or less.如果我在 12 月 31 日发布内容,并在 1 月 1 日查看它,我会看到“大约 1 年前”,而我个人认为“大约 1 天前”或更短。

You can use the dateComponents(_:from:to:) method:您可以使用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"
    }
}

And in date(post:) :并在date(post:)

return Calendar.current.estimatedTimeFromNow(date: date)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM