Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do you compare just the time of a Date in Swift?

I have two Date Objects:

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

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

I need to compare just the time of these values and ignore the date

example: 12:00am and 12:01am, 12:01 is later so (12:01am > 12:00am) == true

like image 955
Dylan Avatar asked Jan 14 '17 03:01

Dylan


People also ask

How do I compare two dates in Swift?

let date1 = Date() let date2 = Date(). addingTimeInterval(100) if date1 == date2 { ... } else if date1 > date2 { ... } else if date1 < date2 { ... } if i want to ignore time. e.g. 2019-05-14 12:08:14 +0000 == 2019-05-14 should return true.

How do you compare date strings?

To compare two date strings:Pass the strings to the Date() constructor to create 2 Date objects. Compare the output from calling the getTime() method on the dates.

How to work with dates in Swift?

In Swift, working with dates is straightforward. In addition to comparing dates and calculating time intervals, you can fully customize the date format. Better yet, you can use a time format of a specific country without knowing the format yourself. You can also choose to work with separate date components, such as years, months, days, hours, etc.

What are datecomponents in Swift?

Last, but not least, DateComponents can also be used as the amount of time that passed between one Date and another. Here is an example: There are many ways of handling the Date type in Swift, as well as many uses for it.

How do you add a time interval to a date?

If you want a time interval different from now use the constructor 'Date (timeIntervalSinceNow:)' //: Gives you a date one minute from now. If you want a date where you add or subtract a time interval, use 'Date (timeInterval:since:)' //: Gives us a date an hour from the previous date.

What is a time interval?

This is a measure of time using seconds. They are of Double type. I’ll set a few constants using time intervals for day, hour and minute. You can set a date based on the time interval.


4 Answers

This is the route I took in the end, which makes it easy to compare just the time of a Date in swift

New Object Time:

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

Date Extension for easy access: //Adds ability to just get the time from a date:

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

Example:

let firstDate = Date()
let secondDate = firstDate

//Will return true
let timeEqual = firstDate.time == secondDate.time
like image 66
Dylan Avatar answered Oct 20 '22 12:10

Dylan


Much simpler than accepted answer:

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)
like image 20
Bartek Spitza Avatar answered Oct 20 '22 12:10

Bartek Spitza


My approach would be to use Calendar to make them Date objects with the same day and then comparing them using for example timeIntervalSinceReferenceDate.

Another, cleaner (but most likely with more lines of resulting code) would be to create extension for Date called secondsFromBeginningOfTheDay() -> TimeInterval and then comparing the resulting double values.

Example based on the second approach:

// 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
like image 9
MirekE Avatar answered Oct 20 '22 12:10

MirekE


My solution for comparing two times of day while ignoring the date:

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

Now you can compare the integers time1 and time2 without regard to the day. You could add the seconds/60 if you need more precision.

like image 8
Wayne Henderson Avatar answered Oct 20 '22 10:10

Wayne Henderson