Get total step count for every date in HealthKit - objective-c

What's the best way to get a total step count for every day recorded in HealthKit.
With HKSampleQuery's method initWithSampleType (see below) I can set a start and end date for the query using NSPredicate, but the method returns an array with many HKQuantitySamples per day.
- (instancetype)initWithSampleType:(HKSampleType *)sampleType
predicate:(NSPredicate *)predicate
limit:(NSUInteger)limit
sortDescriptors:(NSArray *)sortDescriptors
resultsHandler:(void (^)(HKSampleQuery *query,
NSArray *results,
NSError *error))resultsHandler
I guess I can query all recorded step counts and go through the array and calculate the total step count for each day, but I'm hoping for an easier solution as there will be thousands of HKSampleQuery objects. Is there a way to have initWithSampleType return a total step count per day?

You should use HKStatisticsCollectionQuery:
NSCalendar *calendar = [NSCalendar currentCalendar];
NSDateComponents *interval = [[NSDateComponents alloc] init];
interval.day = 1;
NSDateComponents *anchorComponents = [calendar components:NSCalendarUnitDay | NSCalendarUnitMonth | NSCalendarUnitYear
fromDate:[NSDate date]];
anchorComponents.hour = 0;
NSDate *anchorDate = [calendar dateFromComponents:anchorComponents];
HKQuantityType *quantityType = [HKObjectType quantityTypeForIdentifier:HKQuantityTypeIdentifierStepCount];
// Create the query
HKStatisticsCollectionQuery *query = [[HKStatisticsCollectionQuery alloc] initWithQuantityType:quantityType
quantitySamplePredicate:nil
options:HKStatisticsOptionCumulativeSum
anchorDate:anchorDate
intervalComponents:interval];
// Set the results handler
query.initialResultsHandler = ^(HKStatisticsCollectionQuery *query, HKStatisticsCollection *results, NSError *error) {
if (error) {
// Perform proper error handling here
NSLog(#"*** An error occurred while calculating the statistics: %# ***",error.localizedDescription);
}
NSDate *endDate = [NSDate date];
NSDate *startDate = [calendar dateByAddingUnit:NSCalendarUnitDay
value:-7
toDate:endDate
options:0];
// Plot the daily step counts over the past 7 days
[results enumerateStatisticsFromDate:startDate
toDate:endDate
withBlock:^(HKStatistics *result, BOOL *stop) {
HKQuantity *quantity = result.sumQuantity;
if (quantity) {
NSDate *date = result.startDate;
double value = [quantity doubleValueForUnit:[HKUnit countUnit]];
NSLog(#"%#: %f", date, value);
}
}];
};
[self.healthStore executeQuery:query];

Port to Swift with no dependency to SwiftDate library
let calendar = NSCalendar.current
let interval = NSDateComponents()
interval.day = 1
var anchorComponents = calendar.dateComponents([.day, .month, .year], from: NSDate() as Date)
anchorComponents.hour = 0
let anchorDate = calendar.date(from: anchorComponents)
// Define 1-day intervals starting from 0:00
let stepsQuery = HKStatisticsCollectionQuery(quantityType: stepsCount!, quantitySamplePredicate: nil, options: .cumulativeSum, anchorDate: anchorDate!, intervalComponents: interval as DateComponents)
// Set the results handler
stepsQuery.initialResultsHandler = {query, results, error in
let endDate = NSDate()
let startDate = calendar.date(byAdding: .day, value: -7, to: endDate as Date, wrappingComponents: false)
if let myResults = results{
myResults.enumerateStatistics(from: startDate!, to: endDate as Date) { statistics, stop in
if let quantity = statistics.sumQuantity(){
let date = statistics.startDate
let steps = quantity.doubleValue(for: HKUnit.count())
print("\(date): steps = \(steps)")
//NOTE: If you are going to update the UI do it in the main thread
DispatchQueue.main.async {
//update UI components
}
}
} //end block
} //end if let
}
healthStore?.execute(stepsQuery)

Modified #sebastianr's answer using core Swift classes, for just for testing I am returning only steps for just one day, once you have more days you can create a dictionary of Dates and step count and return it
func getStepCountPerDay(completion:#escaping (_ count: Double)-> Void){
guard let sampleType = HKObjectType.quantityType(forIdentifier: .stepCount)
else {
return
}
let calendar = Calendar.current
var dateComponents = DateComponents()
dateComponents.day = 1
var anchorComponents = calendar.dateComponents([.day, .month, .year], from: Date())
anchorComponents.hour = 0
let anchorDate = calendar.date(from: anchorComponents)
let stepsCumulativeQuery = HKStatisticsCollectionQuery(quantityType: sampleType, quantitySamplePredicate: nil, options: .cumulativeSum, anchorDate: anchorDate!, intervalComponents: dateComponents
)
// Set the results handler
stepsCumulativeQuery.initialResultsHandler = {query, results, error in
let endDate = Date()
let startDate = calendar.date(byAdding: .day, value: 0, to: endDate, wrappingComponents: false)
if let myResults = results{
myResults.enumerateStatistics(from: startDate!, to: endDate as Date) { statistics, stop in
if let quantity = statistics.sumQuantity(){
let date = statistics.startDate
let steps = quantity.doubleValue(for: HKUnit.count())
print("\(date): steps = \(steps)")
completion(steps)
//NOTE: If you are going to update the UI do it in the main thread
DispatchQueue.main.async {
//update UI components
}
}
} //end block
} //end if let
}
HKHealthStore().execute(stepsCumulativeQuery)
}

Here is a translation that currently works for Swift 2.0, using the SwiftDate library.
let type = HKSampleType.quantityTypeForIdentifier(HKQuantityTypeIdentifierStepCount)
let startDate = NSDate().beginningOfDay().oneWeekAgo()
let interval = NSDateComponents()
interval.day = 1
let predicate = HKQuery.predicateForSamplesWithStartDate(startDate, endDate: NSDate(), options: .StrictStartDate)
let query = HKStatisticsCollectionQuery(quantityType: type!, quantitySamplePredicate: predicate, options: [.CumulativeSum], anchorDate: NSDate().begginingOfDay(), intervalComponents:interval)
query.initialResultsHandler = { query, results, error in
let endDate = NSDate()
let startDate = NSDate().beginningOfDay().oneWeekAgo()
if let myResults = results{
myResults.enumerateStatisticsFromDate(startDate, toDate: endDate) {
statistics, stop in
if let quantity = statistics.sumQuantity() {
let date = statistics.startDate
let steps = quantity.doubleValueForUnit(HKUnit.countUnit())
print("\(date): steps = \(steps)")
}
}
}
}
healthKitStore.executeQuery(query)

I wrapped mine in a completion block (objective -c). I found what was best was to set the startDate for the query to todays date at midnight. Hope this helps, feel free to copy/paste to get started
-(void)fetchHourlyStepsWithCompletionHandler:(void (^)(NSMutableArray *, NSError *))completionHandler {
NSMutableArray *mutArray = [NSMutableArray new];
NSCalendar *calendar = [NSCalendar autoupdatingCurrentCalendar];
NSDate *startDate = [calendar dateBySettingHour:0 minute:0 second:0 ofDate:[NSDate date] options:0];
NSDate *endDate = [NSDate date]; // Whatever you need in your case
HKQuantityType *type = [HKObjectType quantityTypeForIdentifier:HKQuantityTypeIdentifierStepCount];
// Your interval: sum by hour
NSDateComponents *intervalComponents = [[NSDateComponents alloc] init];
intervalComponents.hour = 1;
// Example predicate
NSPredicate *predicate = [HKQuery predicateForSamplesWithStartDate:startDate endDate:endDate options:HKQueryOptionStrictStartDate];
HKStatisticsCollectionQuery *query = [[HKStatisticsCollectionQuery alloc] initWithQuantityType:type quantitySamplePredicate:predicate options:HKStatisticsOptionCumulativeSum anchorDate:startDate intervalComponents:intervalComponents];
query.initialResultsHandler = ^(HKStatisticsCollectionQuery *query, HKStatisticsCollection *results, NSError *error) {
[results enumerateStatisticsFromDate:startDate toDate:endDate
withBlock:^(HKStatistics *result, BOOL *stop) {
if (!result) {
if (completionHandler) {
completionHandler(nil, error);
}
return;
}
HKQuantity *quantity = result.sumQuantity;
NSDate *startDate = result.startDate;
NSDateFormatter *formatter = [[NSDateFormatter alloc]init];
formatter.dateFormat = #"h a";
NSString *dateString = [formatter stringFromDate:startDate];
double steps = [quantity doubleValueForUnit:[HKUnit countUnit]];
NSDictionary *dict = #{#"steps" : #(steps),
#"hour" : dateString
};
[mutArray addObject:dict];
}];
if (completionHandler) {
completionHandler(mutArray, error);
}
};
[self.healthStore executeQuery:query];
}

With Updated Swift 2.0 & SwiftDate library.
let type = HKSampleType.quantityTypeForIdentifier(HKQuantityTypeIdentifierStepCount)
let startDate = NSDate().beginningOfDay
let interval = NSDateComponents()
interval.day = 1
let predicate = HKQuery.predicateForSamplesWithStartDate(startDate, endDate: NSDate(), options: .StrictStartDate)
let query = HKStatisticsCollectionQuery(quantityType: type!, quantitySamplePredicate: predicate, options: [.CumulativeSum], anchorDate: NSDate().beginningOfDay, intervalComponents:interval)
query.initialResultsHandler = { query, results, error in
let endDate = NSDate()
let startDate = NSDate().beginningOfDay
if let myResults = results{
myResults.enumerateStatisticsFromDate(startDate, toDate: endDate) {
statistics, stop in
if let quantity = statistics.sumQuantity() {
let date = statistics.startDate
let steps = quantity.doubleValueForUnit(HKUnit.countUnit())
print("\(date): steps = \(steps)")
}
}
}
}
healthKitStore.executeQuery(query)

Related

Label based on Day of the Week

I am trying to display Happy Hour specials for bars according to the day of the week it is but for some reason the label is not matching with the current date. I am fairly new to Xcode so I am not sure if I am overlooking something.. Here is my code:
NSDate *today = [NSDate date];
NSDateFormatter *dateFormat = [[NSDateFormatter alloc] init];
[dateFormat setDateFormat:#"EEEE"];
NSString *dateString = [dateFormat stringFromDate:today];
NSLog(#"date: %#", dateString);
lblTitle.text = pawpost.title;
lblPhone.text = pawpost.phone;
if ((dateString = #"Thursday")) {
happy.text = pawpost.thu;
}
else if ((dateString = #"Monday")) {
happy.text = pawpost.mon;
}
else if ((dateString = #"Tuesday")) {
happy.text = pawpost.tue;
}
else if ((dateString = #"Wednseday")) {
happy.text = pawpost.wed;
}
else if ((dateString = #"Friday")) {
happy.text = pawpost.fri;
}
else if ((dateString = #"Saturday")) {
happy.text = pawpost.sat;
}
else if ((dateString = #"Sunday")) {
happy.text = pawpost.sun;
}
You'll want to use the isEqualToString: method:
if([dateString isEqualToString:#"Monday"]) {
happy.text = pawpost.mon;
}
You might also want to localize that #"Monday" string literal.

How to create a date object for tomorrow at 8am

I am normally pretty good with this, but I am having trouble with the NSDate object. I need a NSDate object set for tomorrow at 8am (relatively). How would I do this and what is the simplest method?
Here's how WWDC 2011 session 117 - Performing Calendar Calculations taught me:
NSDate* now = [NSDate date] ;
NSDateComponents* tomorrowComponents = [NSDateComponents new] ;
tomorrowComponents.day = 1 ;
NSCalendar* calendar = [NSCalendar currentCalendar] ;
NSDate* tomorrow = [calendar dateByAddingComponents:tomorrowComponents toDate:now options:0] ;
NSDateComponents* tomorrowAt8AMComponents = [calendar components:(NSEraCalendarUnit|NSYearCalendarUnit|NSMonthCalendarUnit|NSDayCalendarUnit) fromDate:tomorrow] ;
tomorrowAt8AMComponents.hour = 8 ;
NSDate* tomorrowAt8AM = [calendar dateFromComponents:tomorrowAt8AMComponents] ;
Too bad iOS doesn't have [NSDate dateWithNaturalLanguageString:#"tomorrow at 8:00 am"]. Thanks, rmaddy, for pointing that out.
In Swift 2.1:
let now = NSDate()
let tomorrowComponents = NSDateComponents()
tomorrowComponents.day = 1
let calendar = NSCalendar.currentCalendar()
if let tomorrow = calendar.dateByAddingComponents(tomorrowComponents, toDate: now, options: NSCalendarOptions.MatchFirst) {
let flags: NSCalendarUnit = [.Era, .Year, .Month, .Day]
let tomorrowValidTime: NSDateComponents = calendar.components(flags, fromDate: tomorrow)
tomorrowValidTime.hour = 7
if let tomorrowMorning = calendar.dateFromComponents(tomorrowValidTime) {
return tomorrowMorning
}
}
Swift 3+
private func tomorrowMorning() -> Date? {
let now = Date()
var tomorrowComponents = DateComponents()
tomorrowComponents.day = 1
let calendar = Calendar.current
if let tomorrow = calendar.date(byAdding: tomorrowComponents, to: now) {
let components: Set<Calendar.Component> = [.era, .year, .month, .day]
var tomorrowValidTime = calendar.dateComponents(components, from: tomorrow)
tomorrowValidTime.hour = 7
if let tomorrowMorning = calendar.date(from: tomorrowValidTime) {
return tomorrowMorning
}
}
return nil
}

Reliably checking whether NSDate falls within given hour, day or week

I need to take a stored NSDate and reliably determine whether it falls within the current moment's hour, day or week. I seem to have hacked together a solution, but not having solved this problem before, am not entirely confident that it's a reliable one.
Will this survive user-set 12 vs 24 hour time? the date formatting guide indicates that this user setting can lead to some unanticipated date behavior: "In iOS, the user can override the default AM/PM versus 24-hour time setting. This may cause NSDateFormatter to rewrite the format string you set."
What about the basic code pattern for this problem? Does this code seem to reliably serve its purpose? I hate to post a "check my code" sort of question, but it's an unfamiliar-enough problem to me, and tricky enough to rigorously test, that it seemed justified. NSDateFormatter is also relatively new to me; another motivation for the question.
NOTE: The main source of my nervousness is that converting dates to strings and then doing a string compare seems an inherently fragile method of solving this problem. But it's the best I could come up with.
Quick reference: the dateFormats I used for each of the three cases were:
dateFormat = #"yyyyMMddHH"; // For "this hour" check
dateFormat = #"yyyyMMdd"; // For "today" check
dateFormat = #"yyyyww"; // For "this week" check
Thanks! Code Follows:
- (BOOL)didThisCycle {
// Case 1: hourly; Case 2: daily; Case 3: weekly
BOOL did = NO;
NSDate *now = [NSDate date];
NSDate *lastDid = [self.didDates lastObject];
if (![lastDid isKindOfClass:[NSDate class]]) { // Crash protection
return NO;
}
int type = [self.goalType intValue];
switch (type) {
case 1:
{
// If hourly check hour
NSDateFormatter *formatter = [[[NSDateFormatter alloc] init] autorelease];
formatter.dateFormat = #"yyyyMMddHH";
NSString *nowString = [formatter stringFromDate:now];
NSString *lastDidString = [formatter stringFromDate:lastDid];
if ([nowString isEqualToString:lastDidString]) {
did = YES;
} else {
did = NO;
}
break;
}
case 2:
{
// If daily check day
NSDateFormatter *formatter = [[[NSDateFormatter alloc] init] autorelease];
formatter.dateFormat = #"yyyyMMdd";
NSString *nowString = [formatter stringFromDate:now];
NSString *lastDidString = [formatter stringFromDate:lastDid];
if ([nowString isEqualToString:lastDidString]) {
did = YES;
} else {
did = NO;
}
break;
}
case 3:
{
// If weekly check week
NSDateFormatter *formatter = [[[NSDateFormatter alloc] init] autorelease];
formatter.dateFormat = #"yyyyww";
NSString *nowString = [formatter stringFromDate:now];
NSString *lastDidString = [formatter stringFromDate:lastDid];
if ([nowString isEqualToString:lastDidString]) {
did = YES;
} else {
did = NO;
}
break;
}
default:
{
did = NO;
break;
}
}
return did;
}
Use the NSDateComponents class, like so:
NSDate *someDate = // whatever
NSDate *now = [NSDate date];
NSDateComponents *thenComponents = [[NSCalendar currentCalendar] components:NSHourCalendarUnit|NSDayCalendarUnit|NSMonthCalendarUnit|NSYearCalendarUnit fromDate:someDate];
NSDateComponents *nowComponents = [[NSCalendar currentCalendar] components:NSHourCalendarUnit|NSDayCalendarUnit|NSMonthCalendarUnit|NSYearCalendarUnit fromDate:now];
if([thenComponents year] == [nowComponents year] && [thenComponents month] == [nowComponents month] && [thenComponents day] == [nowComponents day] && [thenComponents hour] == [nowComponents hour])
{
// hooray
}
Remove the “hour” component if you just want to check the day, or remove both that and “day” (and replace with NSWeekCalendarUnit and the -week method) to check the week.

Get all dates (not days) between two NSDates

How can I get all the dates that come in between 2 dates?
For example:
Start date = 2011/01/25
End date = 2011/02/03
1) Find the no of days between two dates. Then,
for(i=0;i<noofdays;i++)
{
//Find the next date
//add to the array
}
To find number of days
To find next date
NSCalendarUnit serves for defining the step between the dates & taking care of the dates being normalized.
iOS 8 API, Swift 2.0
func generateDates(calendarUnit: NSCalendarUnit, startDate: NSDate, endDate: NSDate) -> [NSDate] {
let calendar = NSCalendar.currentCalendar()
let normalizedStartDate = calendar.startOfDayForDate(startDate)
let normalizedEndDate = calendar.startOfDayForDate(endDate)
var dates = [normalizedStartDate]
var currentDate = normalizedStartDate
repeat {
currentDate = calendar.dateByAddingUnit(calendarUnit, value: 1, toDate: currentDate, options: NSCalendarOptions.MatchNextTime)!
dates.append(currentDate)
} while !calendar.isDate(currentDate, inSameDayAsDate: normalizedEndDate)
return dates
}
To find all days between two NSDates:
- (void)cerateDaysArray{
_daysArray = [NSMutableArray new];
NSCalendar *calendar = [[NSCalendaralloc]initWithCalendarIdentifier:NSGregorianCalendar];
[calendar setTimeZone:[NSTimeZone systemTimeZone]];
NSDate *startDate = [_minDate copy];
NSDateComponents *deltaDays = [NSDateComponents new];
[deltaDays setDay:1];
[_daysArray addObject:startDate];
while ([startDate compare:_maxDate] == NSOrderedAscending) {
startDate = [calendar dateByAddingComponents:deltaDays toDate:startDate options:0];
[_daysArray addObject:startDate];
}
}

Comparing dates [duplicate]

I have two dates: 2009-05-11 and the current date. I want to check whether the given date is the current date or not. How is this possible.
Cocoa has couple of methods for this:
in NSDate
– isEqualToDate:
– earlierDate:
– laterDate:
– compare:
When you use - (NSComparisonResult)compare:(NSDate *)anotherDate ,you get back one of these:
The receiver and anotherDate are exactly equal to each other, NSOrderedSame
The receiver is later in time than anotherDate, NSOrderedDescending
The receiver is earlier in time than anotherDate, NSOrderedAscending.
example:
NSDate * now = [NSDate date];
NSDate * mile = [[NSDate alloc] initWithString:#"2001-03-24 10:45:32 +0600"];
NSComparisonResult result = [now compare:mile];
NSLog(#"%#", now);
NSLog(#"%#", mile);
switch (result)
{
case NSOrderedAscending: NSLog(#"%# is in future from %#", mile, now); break;
case NSOrderedDescending: NSLog(#"%# is in past from %#", mile, now); break;
case NSOrderedSame: NSLog(#"%# is the same as %#", mile, now); break;
default: NSLog(#"erorr dates %#, %#", mile, now); break;
}
[mile release];
Here buddy. This function will match your date with any specific date and will be able to tell whether they match or not. You can also modify the components to match your requirements.
- (BOOL)isSameDay:(NSDate*)date1 otherDay:(NSDate*)date2 {
NSCalendar* calendar = [NSCalendar currentCalendar];
unsigned unitFlags = NSYearCalendarUnit | NSMonthCalendarUnit | NSDayCalendarUnit;
NSDateComponents* comp1 = [calendar components:unitFlags fromDate:date1];
NSDateComponents* comp2 = [calendar components:unitFlags fromDate:date2];
return [comp1 day] == [comp2 day] &&
[comp1 month] == [comp2 month] &&
[comp1 year] == [comp2 year];}
Regards,
Naveed Butt
NSDate *today = [NSDate date]; // it will give you current date
NSDate *newDate = [NSDate dateWithString:#"xxxxxx"]; // your date
NSComparisonResult result;
//has three possible values: NSOrderedSame,NSOrderedDescending, NSOrderedAscending
result = [today compare:newDate]; // comparing two dates
if(result==NSOrderedAscending)
NSLog(#"today is less");
else if(result==NSOrderedDescending)
NSLog(#"newDate is less");
else
NSLog(#"Both dates are same");
There are other ways that you may use to compare an NSDate objects. Each of the
methods will be more efficient at certain tasks. I have chosen the compare method
because it will handle most of your basic date comparison needs.
This category offers a neat way to compare NSDates:
#import <Foundation/Foundation.h>
#interface NSDate (Compare)
-(BOOL) isLaterThanOrEqualTo:(NSDate*)date;
-(BOOL) isEarlierThanOrEqualTo:(NSDate*)date;
-(BOOL) isLaterThan:(NSDate*)date;
-(BOOL) isEarlierThan:(NSDate*)date;
//- (BOOL)isEqualToDate:(NSDate *)date; already part of the NSDate API
#end
And the implementation:
#import "NSDate+Compare.h"
#implementation NSDate (Compare)
-(BOOL) isLaterThanOrEqualTo:(NSDate*)date {
return !([self compare:date] == NSOrderedAscending);
}
-(BOOL) isEarlierThanOrEqualTo:(NSDate*)date {
return !([self compare:date] == NSOrderedDescending);
}
-(BOOL) isLaterThan:(NSDate*)date {
return ([self compare:date] == NSOrderedDescending);
}
-(BOOL) isEarlierThan:(NSDate*)date {
return ([self compare:date] == NSOrderedAscending);
}
#end
Simple to use:
if([aDateYouWantToCompare isEarlierThanOrEqualTo:[NSDate date]]) // [NSDate date] is now
{
// do your thing ...
}
If you make both dates NSDates you can use NSDate's compare: method:
NSComparisonResult result = [Date2 compare:Date1];
if(result==NSOrderedAscending)
NSLog(#"Date1 is in the future");
else if(result==NSOrderedDescending)
NSLog(#"Date1 is in the past");
else
NSLog(#"Both dates are the same");
You can take a look at the docs here.
By this method also you can compare two dates
NSDate * dateOne = [NSDate date];
NSDate * dateTwo = [NSDate date];
if([dateOne compare:dateTwo] == NSOrderedAscending)
{
}
The best way I found was to check the difference between the given date and today:
NSCalendar* calendar = [NSCalendar currentCalendar];
NSDate* now = [NSDate date];
int differenceInDays =
[calendar ordinalityOfUnit:NSCalendarUnitDay inUnit:NSCalendarUnitEra forDate:date] -
[calendar ordinalityOfUnit:NSCalendarUnitDay inUnit:NSCalendarUnitEra forDate:now];
According to Listing 13 of Calendrical Calculations in Apple's Date and Time Programming Guide [NSCalendar ordinalityOfUnit:NSDayCalendarUnit inUnit: NSEraCalendarUnit forDate:myDate] gives you the number of midnights since the start of the era.
This way it's easy to check whether the date is yesterday, today, or tomorrow.
switch (differenceInDays) {
case -1:
dayString = #"Yesterday";
break;
case 0:
dayString = #"Today";
break;
case 1:
dayString = #"Tomorrow";
break;
default: {
NSDateFormatter* dayFormatter = [[NSDateFormatter alloc] init];
[dayFormatter setLocale:usLocale];
[dayFormatter setDateFormat:#"dd MMM"];
dayString = [dayFormatter stringFromDate: date];
break;
}
}
NSDateFormatter *df= [[NSDateFormatter alloc] init];
[df setDateFormat:#"yyyy-MM-dd"];
NSDate *dt1 = [[NSDate alloc] init];
NSDate *dt2 = [[NSDate alloc] init];
dt1=[df dateFromString:#"2011-02-25"];
dt2=[df dateFromString:#"2011-03-25"];
NSComparisonResult result = [dt1 compare:dt2];
switch (result)
{
case NSOrderedAscending: NSLog(#"%# is greater than %#", dt2, dt1); break;
case NSOrderedDescending: NSLog(#"%# is less %#", dt2, dt1); break;
case NSOrderedSame: NSLog(#"%# is equal to %#", dt2, dt1); break;
default: NSLog(#"erorr dates %#, %#", dt2, dt1); break;
}
Enjoy coding......
In Cocoa, to compare dates, use one of isEqualToDate, compare, laterDate, and earlierDate methods on NSDate objects, instantiated with the dates you need.
Documentation:
http://developer.apple.com/documentation/Cocoa/Reference/Foundation/Classes/NSDate_Class/Reference/Reference.html#//apple_ref/occ/instm/NSDate/isEqualToDate:
http://developer.apple.com/documentation/Cocoa/Reference/Foundation/Classes/NSDate_Class/Reference/Reference.html#//apple_ref/occ/instm/NSDate/earlierDate:
http://developer.apple.com/documentation/Cocoa/Reference/Foundation/Classes/NSDate_Class/Reference/Reference.html#//apple_ref/occ/instm/NSDate/laterDate:
http://developer.apple.com/documentation/Cocoa/Reference/Foundation/Classes/NSDate_Class/Reference/Reference.html#//apple_ref/occ/instm/NSDate/compare:
What you really need is to compare two objects of the same kind.
Create an NSDate out of your string date (#"2009-05-11") :
http://blog.evandavey.com/2008/12/how-to-convert-a-string-to-nsdate.html
If the current date is a string too, make it an NSDate. If its already an NSDate, leave it.
Here's the Swift variant on Pascal's answer:
extension NSDate {
func isLaterThanOrEqualTo(date:NSDate) -> Bool {
return !(self.compare(date) == NSComparisonResult.OrderedAscending)
}
func isEarlierThanOrEqualTo(date:NSDate) -> Bool {
return !(self.compare(date) == NSComparisonResult.OrderedDescending)
}
func isLaterThan(date:NSDate) -> Bool {
return (self.compare(date) == NSComparisonResult.OrderedDescending)
}
func isEarlierThan(date:NSDate) -> Bool {
return (self.compare(date) == NSComparisonResult.OrderedAscending)
}
}
Which can be used as:
self.expireDate.isEarlierThanOrEqualTo(NSDate())
Here's the function from Naveed Rafi's answer converted to Swift if anyone else is looking for it:
func isSameDate(#date1: NSDate, date2: NSDate) -> Bool {
let calendar = NSCalendar()
let date1comp = calendar.components(.YearCalendarUnit | .MonthCalendarUnit | .DayCalendarUnit, fromDate: date1)
let date2comp = calendar.components(.YearCalendarUnit | .MonthCalendarUnit | .DayCalendarUnit, fromDate: date2)
return (date1comp.year == date2comp.year) && (date1comp.month == date2comp.month) && (date1comp.day == date2comp.day)
}
Get Today's Date:
NSDate* date = [NSDate date];
Create a Date From Scratch:
NSDateComponents* comps = [[NSDateComponents alloc]init];
comps.year = 2015;
comps.month = 12;
comps.day = 31;
NSCalendar* calendar = [NSCalendar currentCalendar];
NSDate* date = [calendar dateFromComponents:comps];
Add a day to a Date:
NSDate* date = [NSDate date];
NSDateComponents* comps = [[NSDateComponents alloc]init];
comps.day = 1;
NSCalendar* calendar = [NSCalendar currentCalendar];
NSDate* tomorrow = [calendar dateByAddingComponents:comps toDate:date options:nil];
Subtract a day from a Date:
NSDate* date = [NSDate date];
NSDateComponents* comps = [[NSDateComponents alloc]init];
comps.day = -1;
NSCalendar* calendar = [NSCalendar currentCalendar];
NSDate* yesterday = [calendar dateByAddingComponents:comps toDate:date options:nil];
Convert a Date to a String:
NSDate* date = [NSDate date];
NSDateFormatter* formatter = [[NSDateFormatter alloc]init];
formatter.dateFormat = #"MMMM dd, yyyy";
NSString* dateString = [formatter stringFromDate:date];
Convert a String to a Date:
NSDateFormatter* formatter = [[NSDateFormatter alloc]init];
formatter.dateFormat = #"MMMM dd, yyyy";
NSDate* date = [formatter dateFromString:#"August 02, 2014"];
Find how many days are in a month:
NSDate* date = [NSDate date];
NSCalendar* cal = [NSCalendar currentCalendar];
NSRange currentRange = [cal rangeOfUnit:NSDayCalendarUnit inUnit:NSMonthCalendarUnit forDate:date];
NSInteger numberOfDays = currentRange.length;
Calculate how much time something took:
NSDate* start = [NSDate date];
for(int i = 0; i < 1000000000; i++);
NSDate* end = [NSDate date];
NSTimeInterval duration = [end timeIntervalSinceDate:start];
Find the Day Of Week for a specific Date:
NSDate* date = [NSDate date];
NSCalendar* cal = [NSCalendar currentCalendar];
NSInteger dow = [cal ordinalityOfUnit:NSWeekdayCalendarUnit inUnit:NSWeekCalendarUnit forDate:date];
Then use NSComparisonResult to compare date.
..
NSString *date = #"2009-05-11"
NSString *nowDate = [[[NSDate date]description]substringToIndex: 10];
if([date isEqualToString: nowDate])
{
// your code
}