How to Determine If a Business Is Open Given the Hours of Operation (Swift-Ios)

How to determine if a business is open given the hours of operation (Swift-iOS)

It's just a matter of playing with the timezone, whether you use the user system's timezone or let them choose another one in the app's settings:

let tz = NSTimeZone.defaultTimeZone()
let now = NSCalendar.currentCalendar().componentsInTimeZone(tz, fromDate: NSDate())

if now.weekDay == 2 && now.hour > MonOpen && now.hour < MonClose {
// The store is open
}

How to tell if a business is open after midnight

You can consider that closeTime must be superior to openTime, otherwise its the day after.

so it will become something like:

let realCloseTime = closeTime < openTime ? closeTime + 24 : closeTime
if now.hour! > Int(openTime) && now.hour! < Int(realCloseTime) {}

How to get store opening hours in local timezone from given date-time response? - SWIFT 5

Here is conversion of weekday and time in GMT into PST time zone:

let weekday = 2 // weekday == 1 is Sunday
let hour = 4 // 4:00 am in GMT+0
let minute = 0 // in GMT+0
guard let timeZone = TimeZone(secondsFromGMT: 0) else { return }
var calendar = Calendar(identifier: .gregorian) // Should be the calendar that is used by your server
calendar.timeZone = timeZone
let date = Date()
let dateComponents = calendar.dateComponents(Set(arrayLiteral: Calendar.Component.weekday,
Calendar.Component.hour,
Calendar.Component.minute), from: date)
var dateComponentsDiff = DateComponents()
dateComponentsDiff.day = weekday - dateComponents.weekday!
dateComponentsDiff.hour = hour - dateComponents.hour!
dateComponentsDiff.minute = minute - dateComponents.minute!
guard let arbitraryDate = calendar.date(byAdding: dateComponentsDiff, to: date),
let pstTimeZone = TimeZone(abbreviation: "PST") else { return }
let pstDateComponents = calendar.dateComponents(in: pstTimeZone, from: arbitraryDate)
print("WEEK DAY: \(pstDateComponents.weekday!)\nTIME: \(pstDateComponents.hour!):\(pstDateComponents.minute!)")

Output:

WEEK DAY: 1
TIME: 20:0

How can I calculate some location Open and Close Time with Current Time

Yes, using an if-else statement (conditional) is a good approach. This is how I would go about this (openTime is opening time and closedTime is closing time):

// Set up calendar and unit flags

let calendar = NSCalendar(calendarIdentifier: NSCalendarIdentifierGregorian)

let timeUnitFlags: NSCalendarUnit = [.CalendarUnitHour, .CalendarUnitMinute]

// Retrieve components

let openComponents = calendar.components(timeUnitFlags, fromDate: openTime)
let closedComponents = calendar.components(timeUnitFlags, fromDate: closedTime)
let currentComponents = calendar.components(timeUnitFlags, fromDate: NSDate())

// Convert components into minutes into the day

let openMinutes = (openComponents.hour * 60) + openComponents.minute
let closedMinutes = (closedComponents.hour * 60) + closedComponents.minute
let currentMinutes = (currentComponents.hour * 60) + currentComponents.minute

// Check if open or closed

if currentMinutes >= openMinutes || currentMinutes <= closedMinutes {
// Open
} else {
// Closed
}

However, the code above does not address closing times after midnight or other calendars.

How to check if 24 hours have passed in Swift

You can use UserDefault to save the date upon creation of the record. The syntax will be

UserDefaults.standard.set(Date(), forKey:"creationTime")

Whenever you want to check the saved date, retrieve it in this way

if let date = UserDefaults.standard.object(forKey: "creationTime") as? Date {
if let diff = Calendar.current.dateComponents([.hour], from: date, to: Date()).hour, diff > 24 {
//do something
}
}

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.

Swift - check if a timestamp is yesterday, today, tomorrow, or X days ago

Calendar has methods for all three cases

func isDateInYesterday(_ date: Date) -> Bool
func isDateInToday(_ date: Date) -> Bool
func isDateInTomorrow(_ date: Date) -> Bool

To calculate the days earlier than yesterday use

func dateComponents(_ components: Set<Calendar.Component>, 
from start: Date,
to end: Date) -> DateComponents

pass [.day] to components and get the day property from the result.


This is a function which considers also is in for earlier and later dates by stripping the time part (Swift 3+).

func dayDifference(from interval : TimeInterval) -> String
{
let calendar = Calendar.current
let date = Date(timeIntervalSince1970: interval)
if calendar.isDateInYesterday(date) { return "Yesterday" }
else if calendar.isDateInToday(date) { return "Today" }
else if calendar.isDateInTomorrow(date) { return "Tomorrow" }
else {
let startOfNow = calendar.startOfDay(for: Date())
let startOfTimeStamp = calendar.startOfDay(for: date)
let components = calendar.dateComponents([.day], from: startOfNow, to: startOfTimeStamp)
let day = components.day!
if day < 1 { return "\(-day) days ago" }
else { return "In \(day) days" }
}
}

Alternatively you could use DateFormatter for Yesterday, Today and Tomorrow to get localized strings for free

func dayDifference(from interval : TimeInterval) -> String
{
let calendar = Calendar.current
let date = Date(timeIntervalSince1970: interval)
let startOfNow = calendar.startOfDay(for: Date())
let startOfTimeStamp = calendar.startOfDay(for: date)
let components = calendar.dateComponents([.day], from: startOfNow, to: startOfTimeStamp)
let day = components.day!
if abs(day) < 2 {
let formatter = DateFormatter()
formatter.dateStyle = .short
formatter.timeStyle = .none
formatter.doesRelativeDateFormatting = true
return formatter.string(from: date)
} else if day > 1 {
return "In \(day) days"
} else {
return "\(-day) days ago"
}
}

Update:

In macOS 10.15 / iOS 13 RelativeDateTimeFormatter was introduced to return (localized) strings relative to a specific date.



Related Topics



Leave a reply



Submit