Hi I am trying to check if the current time is within a time range, say 8:00 - 16:30. My code below shows that I can obtain the current time as a string, but I am unsure how
also, the solution below looks short if i want to see if the time is in a specific range during day
var greeting = String()
let date = Date()
let calendar = Calendar.current
let hour = calendar.component(.hour, from: date)
//let minutes = calendar.component(.minute, from: date)
let morning = 3; let afternoon=12; let evening=16; let night=22;
print("Hour: \(hour)")
if morning < hour, hour < afternoon {
greeting = "Good Morning!"
}else if afternoon < hour, hour < evening{
greeting = "Good Afternoon!"
}else if evening < hour, hour < night{
greeting = "Good Evening!"
}else{
greeting = "Good Night"
}
print(greeting)
i guess you could modify it, to check for example, if the months are in certain ranges too, e.g:
sum = "Jan"
win = "March"
Spr = "May"
Aut = "Sept"
and continue from there...
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:
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")
}
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:
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")
}
In Swift 3.0 you can use the new Date value type and compare directly with ==,>,< etc
let now = NSDate()
let nowDateValue = now as Date
let todayAtSevenAM = calendar.date(bySettingHour: 7, minute: 0, second: 0, of: nowDateValue, options: [])
let todayAtTenPM = calendar.date(bySettingHour: 22, minute: 0, second: 0, of: nowDateValue, options: [])
if nowDateValue >= todayAtSevenAM! &&
nowDateValue <= todayAtTenPM!
{
// date is in range
}
Very handy indeed.
You could make NSDate
conform to the Comparable
protocol to be able to use the ==
, !=
, <=
, >=
, >
and <
operators. For example:
extension NSDate : Comparable {}
// To conform to Comparable, NSDate must also conform to Equatable.
// Hence the == operator.
public func == (lhs: NSDate, rhs: NSDate) -> Bool {
return lhs.compare(rhs) == .OrderedSame
}
public func > (lhs: NSDate, rhs: NSDate) -> Bool {
return lhs.compare(rhs) == .OrderedDescending
}
public func < (lhs: NSDate, rhs: NSDate) -> Bool {
return lhs.compare(rhs) == .OrderedAscending
}
public func <= (lhs: NSDate, rhs: NSDate) -> Bool {
return lhs == rhs || lhs < rhs
}
public func >= (lhs: NSDate, rhs: NSDate) -> Bool {
return lhs == rhs || lhs > rhs
}
To use this to check a date was within two dates you could use:
let currentDate = NSDate()
let olderDate = NSDate(timeIntervalSinceNow: -100)
let newerDate = NSDate(timeIntervalSinceNow: 100)
olderDate < currentDate && currentDate < newerDate // Returns true
Here are a few more examples of how to use the operators with NSDate
:
olderDate < newerDate // True
olderDate > newerDate // False
olderDate != newerDate // True
olderDate == newerDate // False
Here is some code I use in one of my current projects. Just set start time as 8:00, end time as 16:30, and timeStamp as current time.
func isTimeStampCurrent(timeStamp:NSDate, startTime:NSDate, endTime:NSDate)->Bool{
timeStamp.earlierDate(endTime) == timeStamp && timeStamp.laterDate(startTime) == timeStamp
}
You can compare date like this.
extension NSDate {
func isGreaterThanDate(dateToCompare: NSDate) -> Bool {
//Declare Variables
var isGreater = false
//Compare Values
if self.compare(dateToCompare) == NSComparisonResult.OrderedDescending {
isGreater = true
}
//Return Result
return isGreater
}
func isLessThanDate(dateToCompare: NSDate) -> Bool {
//Declare Variables
var isLess = false
//Compare Values
if self.compare(dateToCompare) == NSComparisonResult.OrderedAscending {
isLess = true
}
//Return Result
return isLess
}
func equalToDate(dateToCompare: NSDate) -> Bool {
//Declare Variables
var isEqualTo = false
//Compare Values
if self.compare(dateToCompare) == NSComparisonResult.OrderedSame {
isEqualTo = true
}
//Return Result
return isEqualTo
}
func addDays(daysToAdd: Int) -> NSDate {
let secondsInDays: NSTimeInterval = Double(daysToAdd) * 60 * 60 * 24
let dateWithDaysAdded: NSDate = self.dateByAddingTimeInterval(secondsInDays)
//Return Result
return dateWithDaysAdded
}
func addHours(hoursToAdd: Int) -> NSDate {
let secondsInHours: NSTimeInterval = Double(hoursToAdd) * 60 * 60
let dateWithHoursAdded: NSDate = self.dateByAddingTimeInterval(secondsInHours)
//Return Result
return dateWithHoursAdded
}
}