Test whether current time of day is between two TimeIntervals

1.2k views Asked by At

I have 2 TimeIntervals, which just represent date-agnostic times of day (e.g. 8:00 AM and 5:00 PM). So 0 represents exactly midnight, in this case, and 29,040 represents 8:04 AM. I want to check if the phone's time of day is between the two TimeIntervals.

I found a few similar Stack Overflow questions, but none of them really dealt with TimeIntervals. It seems like just using start <= Date().timeIntervalSinceReferenceDate <= end or something wouldn't work, because it would return a huge value.

What's the best way to handle this type of situation in Swift 3?

Edit: To clarify, I don't need to worry about things like daylight savings. As an example, assume that the user only wants certain things in the app to happen between the hours of X and Y, where X and Y are given to me as TimeInterval values since midnight. So it should be sufficient to check if the phone's TimeInterval since midnight on a typical day is between X and Y before completing the action.

2

There are 2 answers

0
Chad On BEST ANSWER

I ended up using DateComponents to calculate a TimeInterval.

let components = Calendar.current.dateComponents(
  [.hour, .minute, .second], from: Date())
guard let seconds = components.second,
  let minutes = components.minute,
  let hours = components.hour else
{
  return false
}
let currentTime = Double(seconds + minutes * 60 + hours * 60 * 60)
return startTime <= currentTime && currentTime <= endTime
2
Code Different On

Date().timeIntervalSinceReferenceDate returns the number of seconds since Jan 1, 2000 so no doubt it's a huge number.

It's inadvisable to store time as seconds since midnight due to this naggy little thing called Daylight Saving Time. Every year, different countries do it on different days and on different hours. For example, even though Britain and France change their clock on the same day (March 26, 2017), one makes the shift from 1AM to 2AM, the other goes from 2AM to 3AM. That's very easy to make for a mess!

Use DateComponents instead:

let calendar = Calendar.current
let startTimeComponent = DateComponents(calendar: calendar, hour: 8)
let endTimeComponent   = DateComponents(calendar: calendar, hour: 17, minute: 30)

let now = Date()
let startOfToday = calendar.startOfDay(for: now)
let startTime    = calendar.date(byAdding: startTimeComponent, to: startOfToday)!
let endTime      = calendar.date(byAdding: endTimeComponent, to: startOfToday)!

if startTime <= now && now <= endTime {
    print("between 8 AM and 5:30 PM")
} else {
    print("not between 8 AM and 5:30 PM")
}