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

后端 未结 8 946
挽巷
挽巷 2020-12-29 10:05

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

相关标签:
8条回答
  • 2020-12-29 10:40

    This code works, check it easily in playground

    let s1 = "22:31"
    let s2 = "14:31"
    let f = DateFormatter()
    f.dateFormat = "HH:mm"
    
    f.date(from: s1)! //"Jan 1, 2000 at 10:31 PM"
    f.date(from: s2)! //"Jan 1, 2000 at 2:31 PM"
    f.date(from: s1)! > f.date(from: s2)!  // true
    
    0 讨论(0)
  • 2020-12-29 10:42

    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.

    0 讨论(0)
  • 2020-12-29 10:47

    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
    
    0 讨论(0)
  • 2020-12-29 10:51

    Let say we got two dates in string format:

    // "2017-01-13 11:40:17 +0000"
    // "2016-03-15 10:22:14 +0000"
    

    We need to convert this strings to Date format, we create DateFormatter() and set the format ("yyyy-MM-dd' 'HH:mm:ssZ") it gonna convert

    //date formatter converts string to date in our case
    let firstDateFormatter = DateFormatter()
    firstDateFormatter.dateFormat = "yyyy-MM-dd' 'HH:mm:ssZ"
    

    Now we can get our date from string to Date format

       //convert string to dates
        if let date1 = firstDateFormatter.date(from: "2017-01-13 09:40:17 +0000"),
            let date2 = firstDateFormatter.date(from: "2016-03-15 10:22:14 +0000") {
        
    

    What we want is to compare only Hours and Minutes. So change dateformat to "HH:mm"

    //we ve got the dates, now switch dateformat for other job
    firstDateFormatter.dateFormat = "HH:mm"
    

    Now get the string value from our date, that only contain "HH:mm"

       // convert date to string ( part of string we want to compare )
            let HHmmDate1 = firstDateFormatter.string(from: date1) //"17:40"
            let HHmmDate2 = firstDateFormatter.string(from: date2) //"18:22"
    

    Final step is to get date from our "HH:mm" values, let say we ask DateFormatter to give us a date, based on time only, in our case "17:40" and "18:22". DateFormatter will put some values for dates, so we get Jan 1, 2000 automatically for both dates, but it will get the time we provide.

       //produce "default" dates with desired HH:mm
        //default means same date, but time is different
            let HH1 = firstDateFormatter.date(from: HHmmDate1) //"Jan 1, 2000 at 5:40 PM"
            let HH2 = firstDateFormatter.date(from: HHmmDate2) //"Jan 1, 2000 at 6:22 PM"
    

    Now we could easily compare dates

     //compare
            HH1! > HH2!
    }
    

    There are many options to compare dates with Calendar also

    0 讨论(0)
  • 2020-12-29 10:52

    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)
    
    0 讨论(0)
  • 2020-12-29 10:56

    This is very simple in Swift if you use Swifter Swift

    date1.day = 1
    date1.month = 1
    date1.year = 2000
    
    date2.day = 1
    date2.month = 1
    date2.year = 2000
    

    now you can use >,<,== operators on date1 and date2 to compare just the time components.

    edit - you could do this your self by extending the date class, for example swifter-swift does the bellow for the day component.

    public var day: Int {
            get {
                return Calendar.current.component(.day, from: self)
            }
            set {
                let allowedRange = Calendar.current.range(of: .day, in: .month, for: self)!
                guard allowedRange.contains(newValue) else { return }
    
                let currentDay = Calendar.current.component(.day, from: self)
                let daysToAdd = newValue - currentDay
                if let date = Calendar.current.date(byAdding: .day, value: daysToAdd, to: self) {
                    self = date
                }
            }
        } 
    
    0 讨论(0)
提交回复
热议问题