Как сравнить два компонента даты - PullRequest
0 голосов
/ 07 марта 2020

Я работаю над приложением, таким как приложение для социальных сетей, где пользователь публикует что-то на стене, публикует данные, сохраненные на сервере, и возвращает в приложение. Я хочу получить время публикации, например, Facebook Instagram et c. (5 часов go ) ответ, который я получаю от сервера:

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

I ' Я использую эту функцию в своем классе UIViewController, чтобы получить время с сервера и вернуть точное время публикации. Расширения в классах 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
}  

}

Теперь проблема заключается в том, когда когда я выкладываю что-то, компоненты текущего времени возвращаются введите описание изображения здесь и ответ на стене что-то вроде этого

введите описание изображения здесь

Ответы [ 2 ]

1 голос
/ 07 марта 2020

Кажется, причина этой ошибки в том, что часы вашего сервера не синхронизированы c со временем устройства. Вы должны выяснить, какие часы имеют «правильное» время, и настроить другие часы. В качестве альтернативы, перепишите код на стороне сервера, чтобы он отвечал текущему времени согласно часам сервера.

В любом случае, вы также заново изобретаете колесо много в своем коде. Ошибка также может быть вызвана кодом обработки даты и времени, который вы написали сами. Вместо этого вы должны использовать встроенные API-интерфейсы, потому что они с меньшей вероятностью содержат ошибки.

Дата, которую вы получаете, имеет формат ISO 8601, поэтому вы можете проанализировать ее с ISO8601DateFormatter. Ваши dateFromServer и timeFromServer методы довольно избыточны.

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
}

Ваш способ найти разницу между двумя датами сомнителен, если не сказать больше. Если я опубликую что-то 31 декабря и посмотрю это 1 января, я увижу «около 1 года go», где я лично ожидаю «около 1 дня go» или меньше.

Вы можете использовать метод 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)
1 голос
/ 07 марта 2020

Ваша дата в ISO 8601 . Так что используйте 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")
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...