skip to Main Content

I have seen questions like these, but from like 6 years ago and do not directly answer the question in my opinion.

I have an array of ‘events’ which follow the Model of:

struct Event: Identifiable{
    var id = UUID().uuidString
    var eventTitle: String
    var eventDescription: String
    var eventDate: Date
}

And example data of:

@Published var storedEvents: [Event] = [
    Event(eventTitle: "Go shopping", eventDescription: "Eggs, flour, butter", eventDate: .init(timeIntervalSince1970: 1646078400)),
    Event(eventTitle: "Lecture with bob", eventDescription: "Room 453", eventDate: .init(timeIntervalSince1970: 1646078708))
    
]

For any given event, I’d like the event’s date to be passed to a function that takes Date and returns true or false whether the given events date is the closest/current event at the current date time compared to all other event’s dates (i.e. if I had two events, one for 8:15 and one for 8:30 and the current time is 8:21, then the first event should be the current one, and therefore returned true from my function.

I have a function working that only takes into account the hour, so if two events have the same hour then they will both be selected and both return true:

func isCurrentHour(date: Date)-> Bool{
    
    let calendar = Calendar.current
    
    let hour = calendar.component(.hour, from: date)
    let currentHour = calendar.component(.hour, from: Date())
    
    return hour == currentHour
}

I have tried sorting the list of dates from the earliest to latest and then comparing each to the current time but I’m not sure how to return true or false on the right event being compared as I have no way of identifying which date belongs to an event.

2

Answers


  1. I think you may be going about this the hard way. It seems what you really want is the earliest event from all events. If so, that can be accomplished like this:

    First, make your Event struct conform to Comparable by date:

    struct Event: Identifiable, Comparable {
        
        var id = UUID().uuidString
        var eventTitle: String
        var eventDescription: String
        var eventDate: Date
        
        static func < (lhs: Event, rhs: Event) -> Bool {
            lhs.eventDate < rhs.eventDate
        }
    }
    

    Then you can return the minimum element in the array. The following will return the earliest event in time, but remember that there is no check in it to make sure that it is the earliest future event, if that is what you need.

    private func earliestEvent(events: [Event]) -> Event? {
        return events.min()
    }
    

    This returns an optional Event as it could fail, such as in the case where the array is empty.

    Edit:

    private func earliestEvent(event: Event, events: [Event]) -> Bool {
        guard let earliestEvent = events.min() else { return false }
        return event == earliestEvent
    }
    
    Login or Signup to reply.
  2. I suggest as a solution to just take the intervals from the dates so far and then compare the two intervals.

    func timeIntervalSince(_ date: Date) -> TimeInterval
    

    Documentation here

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search