how to check if time is within a specific range in swift
There are lots of ways to do this. Personally, I don't like working with strings if I can avoid it. I'd rather deal with date components.
Below is code that creates dates for 8:00 and 16:30, and then compares the dates to see if the current date/time falls in that range.
It's longer than other people's code, but I think it's worth learning how to do calculations with dates using a Calendar:
EDIT #3:
This answer is from a long time ago. I'll leave the old answer below, but here is the current solution:
@CodenameDuchess' answer uses a system function, date(bySettingHour:minute:second:of:matchingPolicy:repeatedTimePolicy:direction:)
Using that function, the code can be simplified to this:
import UIKit
// The function `Calendar.date(bySettingHour:minute:second)` lets you
// create date objects for a given time in the same day of given date
// For example, 8:00 today
let calendar = Calendar.current
let now = Date()
let eight_today = calendar.date(
bySettingHour: 8,
minute: 0,
second: 0,
of: now)!
let four_thirty_today = calendar.date(
bySettingHour: 16,
minute: 30,
second: 0,
of: now)!
// In recent versions of Swift Date objectst are comparable, so you can
// do greater than, less than, or equal to comparisons on dates without
// needing a date extension
if now >= eight_today &&
now <= four_thirty_today
{
print("The time is between 8:00 and 16:30")
}
The old (Swift 2) answer follows, for historical completeness:
This code uses a Calendar object to get the day/month/year of the current date, and adds the desired hour/minute components, and then generates a date for those components.
import UIKit
//-------------------------------------------------------------
//NSDate extensions.
extension NSDate
{
/**
This adds a new method dateAt to NSDate.
It returns a new date at the specified hours and minutes of the receiver
:param: hours: The hours value
:param: minutes: The new minutes
:returns: a new NSDate with the same year/month/day as the receiver, but with the specified hours/minutes values
*/
func dateAt(#hours: Int, minutes: Int) -> NSDate
{
let calendar = NSCalendar(calendarIdentifier: NSCalendarIdentifierGregorian)!
//get the month/day/year componentsfor today's date.
println("Now = \(self)")
let date_components = calendar.components(
NSCalendarUnit.CalendarUnitYear |
NSCalendarUnit.CalendarUnitMonth |
NSCalendarUnit.CalendarUnitDay,
fromDate: self)
//Create an NSDate for 8:00 AM today.
date_components.hour = hours
date_components.minute = minutes
date_components.second = 0
let newDate = calendar.dateFromComponents(date_components)!
return newDate
}
}
//-------------------------------------------------------------
//Tell the system that NSDates can be compared with ==, >, >=, <, and <= operators
extension NSDate: Equatable {}
extension NSDate: Comparable {}
//-------------------------------------------------------------
//Define the global operators for the
//Equatable and Comparable protocols for comparing NSDates
public func ==(lhs: NSDate, rhs: NSDate) -> Bool
{
return lhs.timeIntervalSince1970 == rhs.timeIntervalSince1970
}
public func <(lhs: NSDate, rhs: NSDate) -> Bool
{
return lhs.timeIntervalSince1970 < rhs.timeIntervalSince1970
}
public func >(lhs: NSDate, rhs: NSDate) -> Bool
{
return lhs.timeIntervalSince1970 > rhs.timeIntervalSince1970
}
public func <=(lhs: NSDate, rhs: NSDate) -> Bool
{
return lhs.timeIntervalSince1970 <= rhs.timeIntervalSince1970
}
public func >=(lhs: NSDate, rhs: NSDate) -> Bool
{
return lhs.timeIntervalSince1970 >= rhs.timeIntervalSince1970
}
//-------------------------------------------------------------
let now = NSDate()
let eight_today = now.dateAt(hours: 8, minutes: 0)
let four_thirty_today = now.dateAt(hours:16, minutes: 30)
if now >= eight_today &&
now <= four_thirty_today
{
println("The time is between 8:00 and 16:30")
}
EDIT:
The code in this answer has changed a LOT for Swift 3.
Instead of using NSDate
, it makes more sense to us the native Date
object, and Date
objects are Equatable
and Comparable
"out of the box".
Thus we can get rid of the Equatable
and Comparable
extensions and the definitions for the <
, >
and =
operators.
Then we need to do a fair amount of tweaking of the syntax in the dateAt
function to follow Swift 3 syntax. The new extension looks like this in Swift 3:
Swift 3 version:
import Foundation
extension Date
{
func dateAt(hours: Int, minutes: Int) -> Date
{
let calendar = NSCalendar(calendarIdentifier: NSCalendar.Identifier.gregorian)!
//get the month/day/year componentsfor today's date.
var date_components = calendar.components(
[NSCalendar.Unit.year,
NSCalendar.Unit.month,
NSCalendar.Unit.day],
from: self)
//Create an NSDate for the specified time today.
date_components.hour = hours
date_components.minute = minutes
date_components.second = 0
let newDate = calendar.date(from: date_components)!
return newDate
}
}
let now = Date()
let eight_today = now.dateAt(hours: 8, minutes: 0)
let four_thirty_today = now.dateAt(hours: 16, minutes: 30)
if now >= eight_today &&
now <= four_thirty_today
{
print("The time is between 8:00 and 16:30")
}
Check if current time is between range of times considering after midnight - Swift
Here is my solution that takes a little different approach by using a struct with minute and hour as Int's
struct Time: Comparable {
var hour = 0
var minute = 0
init(hour: Int, minute: Int) {
self.hour = hour
self.minute = minute
}
init(_ date: Date) {
let calendar = Calendar.current
hour = calendar.component(.hour, from: date)
minute = calendar.component(.minute, from: date)
}
static func == (lhs: Time, rhs: Time) -> Bool {
return lhs.hour == rhs.hour && lhs.minute == rhs.minute
}
static func < (lhs: Time, rhs: Time) -> Bool {
return (lhs.hour < rhs.hour) || (lhs.hour == rhs.hour && lhs.minute < rhs.minute)
}
static func create(time: String) -> Time? {
let parts = time.split(separator: ":")
if let hour = Int(parts[0]), let minute = Int(parts[1]) {
return Time(hour: hour, minute: minute)
}
return nil
}
static func isOpen(open: Time, close: Time) -> Bool {
let isClosingAfterMidnight = close.hour < open.hour ? true : false
let currentTime = Time(Date())
if isClosingAfterMidnight {
return currentTime > close && currentTime < open ? false : true
}
return currentTime >= open && currentTime < close
}
}
And it can be used like
if let open = Time.create(time: todayWh.openingAt), let close = Time.create(time: todayWh.closingAt) {
return Time.isOpen(open: open, close: close))
} else {
//error handling
}
It should work also after midnight :) Of course the Time struct could be used directly in the wh array.
Find if current time is between a range
Yes you can using NSDateComponents
which will return the hour in the 24 hour format.
NSDateComponents *components = [[NSCalendar currentCalendar] components:NSHourCalendarUnit fromDate:[NSDate date]];
NSInteger hour = [components hour];
if(hour >= 0 && hour < 12)
NSLog(@"Good morning, foo");
else if(hour >= 12 && hour < 17)
NSLog(@"Good afternoon, foo");
else if(hour >= 17)
NSLog(@"Good evening, foo");
Swift 3
let hour = Calendar.current.component(.hour, from: Date())
if hour >= 0 && hour < 12 {
print("Good Morning")
} else if hour >= 12 && hour < 17 {
print("Good Afternoon")
} else if hour >= 17 {
print("Good Evening")
}
Check if date falls between 2 dates
Swift 2
For a better answer see Swift ≧ 3.
You already have the code for conversion of your date string in KeysData
to NSDate
. Assuming you have the two dates in startdate
and enddate
, all you have to do is check if the current date is in between:
let startDate = ...
let endDate = ...
NSDate().isBetween(date: startDate, andDate: endDate)
extension NSDate {
func isBetweeen(date date1: NSDate, andDate date2: NSDate) -> Bool {
return date1.compare(self) == self.compare(date2)
}
}
Edit: If you want to perform an inclusive range check, use this condition:
extension NSDate {
func isBetween(date date1: NSDate, andDate date2: NSDate) -> Bool {
return date1.compare(self).rawValue * self.compare(date2).rawValue >= 0
}
}
ios- Check whether current time is between two times or not
Try this
NSDateComponents *components = [[NSCalendar currentCalendar] components:NSHourCalendarUnit | NSMinuteCalendarUnit | NSSecondCalendarUnit fromDate:[NSDate date]];
NSInteger currentHour = [components hour];
NSInteger currentMinute = [components minute];
NSInteger currentSecond = [components second];
if (currentHour < 7 || (currentHour > 21 || currentHour == 21 && (currentMinute > 0 || currentSecond > 0))) {
// Do Something
}
Replace 7, 21 with your time
I get this from How to compare time
Swfit- Check whether current time is between two time string
You can set the date formatter defaultDate
for today, parse the date strings, create a DateInterval
with the start and end date and check if it contains now Date()
:
extension Formatter {
static let today: DateFormatter = {
let dateFormatter = DateFormatter()
dateFormatter.locale = .init(identifier: "en_US_POSIX")
dateFormatter.defaultDate = Calendar.current.startOfDay(for: Date())
dateFormatter.dateFormat = "hh:mm a"
return dateFormatter
}()
}
func checkIfCurrentTimeIsBetween(startTime: String, endTime: String) -> Bool {
guard let start = Formatter.today.date(from: startTime),
let end = Formatter.today.date(from: endTime) else {
return false
}
return DateInterval(start: start, end: end).contains(Date())
}
let startTime = "10:30 AM"
let endTime = "06:30 PM"
checkIfCurrentTimeIsBetween(startTime: startTime, endTime: endTime) // true
How to determine date falls in between two dates swift
If you have Date objects, they are Comparable and Equatable. You can write code like:
if breakDate >= startDate && breakDate <= endDate then {
// breakDate is between startDate and endDate
}
Edit:
As pointed out by LeoDabus in the comments, you could also use the pattern match operator (although I personally don't like it)
if startDate ... endDate ~= breakDate then {
// breakDate is between startDate and endDate
}
or contains:
if (startDate...endDate).contains(breakDate) then {
// breakDate is between startDate and endDate
}
If you have date strings, create a date formatter that converts your date strings to Date
objects, then use code like the above.
If the date strings are always in "Internet" date format (ISO 8601), and you are certain they will always be in the same time zone, you can also use string comparison and compare the date strings directly (using any of the above forms of comparison, except maybe contains?)
Check if a given date is the closest to the current date and time compared to an array of dates
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
}
Related Topics
Make Code With Firebase Asynchronous
Unowned Vs. Weak. Why We Should Prefer Unowned
How to Use an Nsattributedstring with a Scrollview in Swiftui
How to Create Custom Notifications in Swift 3
Delete Data from Coredata Swift
How to Override Trait Collection for Initial Uiviewcontroller? (With Storyboard)
Property Observers Willset and Didset; Property Getters and Setters
Load Image from iOS 8 Framework
Swift: How to Read Standard Output in a Child Process Without Waiting for Process to Finish
Swift Sphere Combine Star Data
Swift Spritekit Adding Button Programmatically
How String Comparison Happens in Swift
How to Loop Through View Outlets in a Uiviewcontroller with Swift
How to Create Swift Class for Category
How to Create a Generic Array Extension That Sums Number Types in Swift