Skip to content

Instantly share code, notes, and snippets.

@rnapier
Last active August 29, 2015 14:12
Show Gist options
  • Save rnapier/61332412c87b06b0ee35 to your computer and use it in GitHub Desktop.
Save rnapier/61332412c87b06b0ee35 to your computer and use it in GitHub Desktop.
ClosingTime example code for http://stackoverflow.com/q/27631882/97337
#import <Foundation/Foundation.h>
#import "WeekTimeRange.h"
int main(int argc, const char * argv[]) {
@autoreleasepool {
NSArray *shopHours = @[WTMakeRange(Monday, 7, 30, Tuesday, 0, 0),
WTMakeRange(Tuesday, 7, 30, Wednesday, 0, 0),
WTMakeRange(Wednesday, 7, 30, Thursday, 0, 0),
WTMakeRange(Thursday, 7, 30, Friday, 0, 0),
WTMakeRange(Friday, 7, 30, Friday, 22, 0),
WTMakeRange(Saturday, 9, 0, Saturday, 22, 0),
WTMakeRange(Sunday, 9, 0, Monday, 2, 0)
];
WeekTime *mondayElevenPM = [[WeekTime alloc] initWithWeekday:Monday hour:23 minute:00];
WeekTimeRange *openRange = WTFindOpenRangeIncluding(shopHours, mondayElevenPM);
NSString *result = WTStatus(openRange, mondayElevenPM);
NSLog(@"%@", result);
}
return 0;
}
#import <Foundation/Foundation.h>
typedef enum {
Sunday,
Monday,
Tuesday,
Wednesday,
Thursday,
Friday,
Saturday
} Weekday;
/**
A WeekTime is the first instant of a nominal minute within a week.
Since it is nominal, it is not subject to DST adjustments. If a
particular nominal minute occurs twice due to DST, then the WeekTime
refers to the first instance of that minute. There are 7*24*60 nominal
minutes in a nominal week.
WeekTimes are subject to modular arithmetic (i.e. "they wrap around").
This means that a WeekTime cannot be meaningfully compared to another
WeekTime as greater-than or less-than. WeekTimes can be compared as
equal or between a start and end.
*/
@interface WeekTime : NSObject
- (instancetype)initWithWeekday:(Weekday)weekday hour:(NSInteger)hour minute:(NSInteger)minute;
+ (NSInteger)maxMinute;
@property (nonatomic, readonly) NSInteger minutesSinceStartOfWeek;
@end
#import "WeekTime.h"
@implementation WeekTime
- (instancetype)initWithWeekday:(Weekday)weekday hour:(NSInteger)hour minute:(NSInteger)minute {
NSParameterAssert(weekday >= Sunday && weekday <= Saturday);
NSParameterAssert(hour >= 0 && hour < 24);
NSParameterAssert(minute >= 0 && minute < 60);
self = [super init];
if (self != nil) {
_minutesSinceStartOfWeek = weekday * 24 * 60 + hour * 60 + minute;
}
return self;
}
+ (NSInteger)maxMinute {
return 7 * (24 * 60);
}
@end
#import <Foundation/Foundation.h>
#import "WeekTime.h"
/**
A range of WeekTimes, from the first instant of start to the first
instant of end. Start is included, but end is not. Since WeekTimes
are subject to modular arithmetic, end may be before start.
start == end is currently undefined. You could choose to make it
contain all times or no times. It depends on which is more useful.
*/
@interface WeekTimeRange : NSObject
@property (nonatomic, readonly) WeekTime *start;
@property (nonatomic, readonly) WeekTime *end;
- (instancetype)initWithStart:(WeekTime *)start end:(WeekTime *)end;
- (BOOL)contains:(WeekTime *)time;
@end
/** Convenience to make a WeekTimeRange */
WeekTimeRange *WTMakeRange(Weekday startDay, NSInteger startHour, NSInteger startMinute,
Weekday endDay, NSInteger endHour, NSInteger endMinute);
/** Return the first range in ranges that includes time. If no ranges
include time, then nil. */
WeekTimeRange *WTFindOpenRangeIncluding(NSArray *ranges, WeekTime *time);
/** Figure out the Open/Closed/Closing string */
NSString *WTStatus(WeekTimeRange *range, WeekTime *requestedTime);
#import "WeekTimeRange.h"
@implementation WeekTimeRange
- (instancetype)initWithStart:(WeekTime *)start end:(WeekTime *)end {
NSInteger startMinutes = start.minutesSinceStartOfWeek;
NSInteger endMinutes = end.minutesSinceStartOfWeek;
NSParameterAssert(startMinutes != endMinutes);
self = [super init];
if (self != nil) {
_start = start;
_end = end;
}
return self;
}
- (BOOL)contains:(WeekTime *)time {
NSInteger queryMinutes = time.minutesSinceStartOfWeek;
NSInteger startMinutes = self.start.minutesSinceStartOfWeek;
NSInteger endMinutes = self.end.minutesSinceStartOfWeek;
if (startMinutes < endMinutes) {
return (startMinutes <= queryMinutes &&
queryMinutes < endMinutes);
} else {
return (queryMinutes < endMinutes ||
queryMinutes >= startMinutes);
}
}
@end
WeekTimeRange *WTMakeRange(Weekday startDay, NSInteger startHour, NSInteger startMinute,
Weekday endDay, NSInteger endHour, NSInteger endMinute) {
return [[WeekTimeRange alloc]
initWithStart:[[WeekTime alloc] initWithWeekday:startDay hour:startHour minute:startMinute]
end:[[WeekTime alloc] initWithWeekday:endDay hour:endHour minute:endMinute]];
}
WeekTimeRange *WTFindOpenRangeIncluding(NSArray *ranges, WeekTime *time) {
for (WeekTimeRange *range in ranges) {
if ([range contains:time]) {
return range;
}
}
return nil;
}
NSString *WTStatus(WeekTimeRange *range, WeekTime *requestedTime) {
if (range != nil) {
NSInteger minutesLeft = range.end.minutesSinceStartOfWeek - requestedTime.minutesSinceStartOfWeek;
if (minutesLeft < 0) {
minutesLeft += [WeekTime maxMinute];
}
if (minutesLeft <= 30) {
return [NSString stringWithFormat:@"Closing in %ld minutes", (long)minutesLeft];
} else {
return @"Open";
}
} else {
return @"Closed";
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment