Как сравнить только время свидания в Swift



У меня есть два объекта даты:



1: 2017-01-13 11:40:17 +0000



2: 2016-03-15 10:22:14 +0000



Мне нужно сравнить только время этих значений и игнорировать дату



Пример: 12: 00am и 12: 01am, 12: 01 позже так (12: 01am > 12: 00am) = = true

611   5  

5 ответов:

Мой подход заключается в использовании Calendar чтобы сделать их Date объектами с одним и тем же днем, а затем сравнить их, используя, например,timeIntervalSinceReferenceDate.

Другим, более чистым (но, скорее всего, с большим количеством строк результирующего кода) было бы создание расширения для Date, называемого secondsFromBeginningOfTheDay() -> TimeInterval, а затем сравнение полученных двойных значений.

Пример, основанный на втором подходе:

// Creating Date from String
let textDate1 = "2017-01-13T12:21:00-0800"
let textDate2 = "2016-03-06T20:12:05-0900"

let dateFormatter: DateFormatter = {
    let formatter = DateFormatter()
    formatter.dateFormat = "yyyy-MM-dd'T'HH:mm:ssZZZ"
    formatter.timeZone = TimeZone.current
    return formatter
} ()

// Dates used for the comparison
let date1 = dateFormatter.date(from: textDate1)
let date2 = dateFormatter.date(from: textDate2)




// Date extensions
extension Date {
    func secondsFromBeginningOfTheDay() -> TimeInterval {
        let calendar = Calendar.current
        // omitting fractions of seconds for simplicity
        let dateComponents = calendar.dateComponents([.hour, .minute, .second], from: self)

        let dateSeconds = dateComponents.hour! * 3600 + dateComponents.minute! * 60 + dateComponents.second!

        return TimeInterval(dateSeconds)
    }

    // Interval between two times of the day in seconds
    func timeOfDayInterval(toDate date: Date) -> TimeInterval {
        let date1Seconds = self.secondsFromBeginningOfTheDay()
        let date2Seconds = date.secondsFromBeginningOfTheDay()
        return date2Seconds - date1Seconds
    }
}

if let date1 = date1, let date2 = date2 {
    let diff = date1.timeOfDayInterval(toDate: date2)

    // as text
    if diff > 0 {
        print("Time of the day in the second date is greater")
    } else if diff < 0 {
        print("Time of the day in the first date is greater")
    } else {
        print("Times of the day in both dates are equal")
    }


    // show interval as as H M S
    let timeIntervalFormatter = DateComponentsFormatter()
    timeIntervalFormatter.unitsStyle = .abbreviated
    timeIntervalFormatter.allowedUnits = [.hour, .minute, .second]
    print("Difference between times since midnight is", timeIntervalFormatter.string(from: diff) ?? "n/a")

}

// Output: 
// Time of the day in the second date is greater
// Difference between times since midnight is 8h 51m 5s

Это маршрут, который я выбрал в конце концов, что позволяет легко сравнить только время даты в swift

Новое Время Объекта:

class Time: Comparable, Equatable {
init(_ date: Date) {
    //get the current calender
    let calendar = Calendar.current

    //get just the minute and the hour of the day passed to it
    let dateComponents = calendar.dateComponents([.hour, .minute], from: date)

        //calculate the seconds since the beggining of the day for comparisions
        let dateSeconds = dateComponents.hour! * 3600 + dateComponents.minute! * 60

        //set the varibles
        secondsSinceBeginningOfDay = dateSeconds
        hour = dateComponents.hour!
        minute = dateComponents.minute!
    }

    init(_ hour: Int, _ minute: Int) {
        //calculate the seconds since the beggining of the day for comparisions
        let dateSeconds = hour * 3600 + minute * 60

        //set the varibles
        secondsSinceBeginningOfDay = dateSeconds
        self.hour = hour
        self.minute = minute
    }

    var hour : Int
    var minute: Int

    var date: Date {
        //get the current calender
        let calendar = Calendar.current

        //create a new date components.
        var dateComponents = DateComponents()

        dateComponents.hour = hour
        dateComponents.minute = minute

        return calendar.date(byAdding: dateComponents, to: Date())!
    }

    /// the number or seconds since the beggining of the day, this is used for comparisions
    private let secondsSinceBeginningOfDay: Int

    //comparisions so you can compare times
    static func == (lhs: Time, rhs: Time) -> Bool {
        return lhs.secondsSinceBeginningOfDay == rhs.secondsSinceBeginningOfDay
    }

    static func < (lhs: Time, rhs: Time) -> Bool {
        return lhs.secondsSinceBeginningOfDay < rhs.secondsSinceBeginningOfDay
    }

    static func <= (lhs: Time, rhs: Time) -> Bool {
        return lhs.secondsSinceBeginningOfDay <= rhs.secondsSinceBeginningOfDay
    }


    static func >= (lhs: Time, rhs: Time) -> Bool {
        return lhs.secondsSinceBeginningOfDay >= rhs.secondsSinceBeginningOfDay
    }


    static func > (lhs: Time, rhs: Time) -> Bool {
        return lhs.secondsSinceBeginningOfDay > rhs.secondsSinceBeginningOfDay
    }
}

Расширение даты для легкого доступа: //Добавляет возможность просто получить время от даты:

extension Date {
    var time: Time {
        return Time(self)
    }
}

Пример:

let firstDate = Date()
let secondDate = firstDate

//Will return true
let timeEqual = firstDate.time == secondDate.time

Мое решение для сравнения двух времен суток, игнорируя дату:

let date1 = some time as a date
let date2 = some other time as a date

let time1 = 60*Calendar.current.component(.hour, from: date1!) + Calendar.current.component(.minute, from: date1!)
let time2 =  60*Calendar.current.component(.hour, from: date2!) + Calendar.current.component(.minute, from: date2!)
Теперь вы можете сравнить целые числа time1 и time2 без учета дня. Вы можете добавить секунды/60, если вам нужно больше точности.

Нет стандартного типа для времени суток. Разумный тип для начала - это просто кортеж:

typealias TimeOfDay = (hour: Int, minute: Int, second: Int)

Чтобы создать эти TimeOfDay значения, вам понадобится Calendar. По умолчанию a Calendar использует общесистемный часовой пояс устройства. Если вы этого не хотите, установите часовой пояс Calendar явно. Пример:

var calendar = Calendar.autoupdatingCurrent
calendar.timeZone = TimeZone(abbreviation: "UTC")!
Теперь вы можете использовать DateFormatter для преобразования строк в Dates (при необходимости), а затем использовать calendar для извлечения компонентов времени суток из Dates:
let strings: [String] = ["2017-01-13 11:40:17 +0000", "2016-03-15 10:22:14 +0000"]
let parser = DateFormatter()
parser.dateFormat = "yyyy-MM-dd HH:mm:ss Z"
let timesOfDay: [TimeOfDay] = strings.map({ (string) -> TimeOfDay in
    let components = calendar.dateComponents([.hour, .minute, .second], from: parser.date(from: string)!)
    return (hour: components.hour!, minute: components.minute!, second: components.second!)
})

Swift.print(timesOfDay)
// Output: [(11, 40, 17), (10, 22, 14)]

Наконец, вы можете сравнить эти значения TimeOfDay. Swift поставляется со стандартными операторами сравнения для кортежей, элементами которых являются Comparable, поэтому этот тип TimeOfDay квалифицируется. Вы можете просто сказать следующее:

if timesOfDay[0] < timesOfDay[1] {
    Swift.print("date[0] comes first")
} else if timesOfDay[0] == timesOfDay[1] {
    Swift.print("times are equal")
} else {
    Swift.print("date[1] comes first")
}

У меня была проблема, и я думаю, что нашел более простое решение, если вы просто хотите сравнить время двух дат. Он действительно чувствует себя немного "хаки", но, кажется, работает хорошо.

SWIFT 4

// date1 and date2 are the dates you want to compare

let calendar = Calendar.current

var newDate = Date(TimeIntervalSinceReferenceDate: 0) // Initiates date at 2001-01-01 00:00:00 +0000
var newDate1 = Date(TimeIntervalSinceReferenceDate: 0) // Same as above

// Recieving the components from the dates you want to compare 
let newDateComponents = calendar.dateComponents([.hour, .minute], from: date1)!
let newDate1Components = calendar.dateComponents([.hour, .minute], from: date2)!

// Adding those components
newDate = calendar.date(byAdding: newDateComponents, to: newDate)
newDate1 = calendar.date(byAdding: newDate1Components, to: newDate1)

Comments

    Ничего не найдено.