Paul
Paul

Reputation: 4430

Swift compare between time

I have the current time, I need to check if the current time is between two times.

But I'm having trouble, as you can see startDate and endDate print past dates.

Can you give me a hand?

func getDate() -> Bool {
    let start = "07:00"
    let end = "19:00"
    let dateFormat = "HH:mm"

    let dateFormatter = DateFormatter()
    dateFormatter.dateFormat = dateFormat

    let startDate = dateFormatter.date(from: start)
    let endDate = dateFormatter.date(from: end)

    let currentDate = Date()

    guard let startDate = startDate, let endDate = endDate else {
      fatalError("Date Format does not match ⚠️")
    }
    
    print(startDate < currentDate && currentDate < endDate)
    print(startDate) //2000-01-01 06:00:00 +0000
    print(endDate) //2000-01-01 22:59:00 +0000
    print(currentDate) //2021-07-13 22:11:05 +0000

    return startDate < currentDate && currentDate < endDate
}

Upvotes: 0

Views: 497

Answers (2)

Leo Dabus
Leo Dabus

Reputation: 236315

You just need to set your DateFormatter defaultDate to the start of the current date. If you would like to allow it to work with midnight (24:00) time as well you just need to set the date formatter isLenient to true. Note that if you create your date formatter inside your method it will create a new date formatter every time you call this method:


extension Formatter {
    static let time: DateFormatter = {
        let formatter = DateFormatter()
        formatter.locale = .init(identifier: "en_US_POSIX")
        formatter.dateFormat = "HH:mm"
        formatter.defaultDate = Calendar.current.startOfDay(for: Date())
        formatter.isLenient = true
        return formatter
    }()
}

func isTimeBetween(start: String, end: String) -> Bool {
    Formatter.time.defaultDate = Calendar.current.startOfDay(for: Date())
    guard
        let start = Formatter.time.date(from: start),
        let end = Formatter.time.date(from: end) else {
        print("invalid time input")
        return false
    }
    print(start.description(with: .current))  // Tuesday, July 13, 2021 at 11:00:00 PM
    print(end.description(with: .current))    // Wednesday, July 14, 2021 at 12:00:00 AM
    print(Date().description(with: .current)) // Tuesday, July 13, 2021 at 11:42:02 PM 
    return start...end ~= Date()
}

isTimeBetween(start: "23:00", end: "24:00")  // true

This will print:

Tuesday, July 13, 2021 at 11:00:00 PM Brasilia Standard Time
Wednesday, July 14, 2021 at 12:00:00 AM Brasilia Standard Time
Tuesday, July 13, 2021 at 11:42:02 PM Brasilia Standard Time

Upvotes: 3

jnpdx
jnpdx

Reputation: 52347

You can use Calendar.current.date(bySetting...) to set the hour/second/minute of an existing date. Then, compare those results.

func getDate() -> Bool {
    let currentDate = Date()
    
    let startDate = Calendar.current.date(bySettingHour: 7, minute: 0, second: 0, of: currentDate)

    let endDate = Calendar.current.date(bySettingHour: 19, minute: 0, second: 0, of: currentDate)

    guard let startDate = startDate, let endDate = endDate else {
      fatalError("Date creation failed ⚠️")
    }
    
    print(startDate < currentDate && currentDate < endDate)
    print(startDate)
    print(endDate)
    print(currentDate)

    return startDate < currentDate && currentDate < endDate
}

Upvotes: 1

Related Questions