Reputation: 47
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
"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. Extentions in Calender and DateFormatter classes and also Help me and guide me to format the current time zone
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
Upvotes: 0
Views: 338
Reputation: 273125
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.
The date you receive is in ISO 8601 format, so you can parse it with a ISO8601DateFormatter
. Your dateFromServer
and timeFromServer
methods are quite redundant.
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.
You can use the dateComponents(_:from:to:)
method:
// 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:)
:
return Calendar.current.estimatedTimeFromNow(date: date)
Upvotes: 1
Reputation:
Your date is in 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")
Upvotes: 1