Skip to content

Instantly share code, notes, and snippets.

@trojanfoe
Last active January 3, 2016 11:09
Show Gist options
  • Save trojanfoe/8454685 to your computer and use it in GitHub Desktop.
Save trojanfoe/8454685 to your computer and use it in GitHub Desktop.
Objective-C NSDate example of checking how many times a day-of-the-month appears between two dates. See: http://stackoverflow.com/questions/21161125/how-many-times-a-specific-day-has-passed-between-two-dates Compile with: clang -g -o dateiter dateiter.m -fobjc-arc -framework Foundation
#import <Foundation/Foundation.h>
static void nextMonth(NSDateComponents *comps) {
NSInteger month = [comps month];
if (month == 12) {
[comps setYear:[comps year] + 1];
[comps setMonth:1];
} else {
[comps setMonth:month + 1];
}
}
int main(int argc, const char **argv) {
@autoreleasepool {
if (argc != 4) {
NSLog(@"usage: %s start-date end-date want-day", argv[0]);
NSLog(@"date format: yyyyMMdd");
return 1;
}
NSTimeZone *tz = [NSTimeZone timeZoneWithAbbreviation:@"UTC"];
NSCalendar *calendar = [[NSCalendar alloc] initWithCalendarIdentifier:NSGregorianCalendar];
[calendar setTimeZone:tz];
NSDateFormatter *formatter = [[NSDateFormatter alloc] init];
[formatter setTimeZone:tz];
[formatter setCalendar:calendar];
[formatter setDateFormat:@"yyyyMMdd"];
NSDate *startDate = [formatter dateFromString:[NSString stringWithUTF8String:argv[1]]];
if (!startDate) {
NSLog(@"Invalid start-date '%s'", argv[1]);
return 2;
}
NSDate *endDate = [formatter dateFromString:[NSString stringWithUTF8String:argv[2]]];
if (!endDate) {
NSLog(@"Invalid end-date '%s'", argv[2]);
return 3;
}
char *endptr;
NSInteger wantDay = (NSInteger)strtol(argv[3], &endptr, 10);
if (wantDay <= 0 || wantDay > 31 || *endptr != '\0') {
NSLog(@"Invalid want-day '%s'", argv[3]);
return 4;
}
NSLog(@"start-date=%@, end-date=%@, want-day=%ld", startDate, endDate, (long)wantDay);
const NSCalendarUnit units = NSEraCalendarUnit|NSYearCalendarUnit|NSMonthCalendarUnit|NSDayCalendarUnit|NSCalendarCalendarUnit|NSTimeZoneCalendarUnit;
NSDateComponents *comps = [calendar components:units
fromDate:startDate];
if ([comps day] > wantDay)
nextMonth(comps); // Missed the first month
[comps setDay:wantDay];
NSInteger count = 0;
while (YES) {
NSDate *compareDate = [calendar dateFromComponents:comps];
if (!compareDate) {
NSLog(@"Failed to create compare date");
return 5;
}
NSLog(@"Comparing %@", [formatter stringFromDate:compareDate]);
if ([compareDate compare:endDate] == NSOrderedDescending)
break;
count++;
nextMonth(comps);
}
NSLog(@"%ld months", (long)count);
}
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment