Hello I had been working with Photos.framework but now I am stuck with predicate comparison of PHFetchOptions class in documents I see that we can use startDate to use in predicate. So my code is this
#interface ViewController ()
{
NSMutableArray * moments;
}
#end
#implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
moments = [NSMutableArray array];
if([PHPhotoLibrary authorizationStatus] == PHAuthorizationStatusNotDetermined)
{
[PHPhotoLibrary requestAuthorization:^(PHAuthorizationStatus status) {
[self loadCollections];
}];
}else
{
[self loadCollections];
}
}
- (void)viewWillAppear:(BOOL)animated
{
[super viewWillAppear:animated];
[self loadCollections];
}
- (NSDate*)dateAddingDays:(NSInteger)days ToDate:(NSDate*)argDate
{
NSCalendar * gregorian = [NSCalendar currentCalendar];
NSDateFormatter * formatter = [[NSDateFormatter alloc]init];
[formatter setDateFormat:#"dd.MM.yyyy"];
NSString * dateString = [formatter stringFromDate:argDate];
NSDate * toWorkDate = [formatter dateFromString:dateString];
NSDateComponents *comps = [[NSDateComponents alloc] init];
[comps setDay:days];
NSDate *date = [gregorian dateByAddingComponents:comps toDate:toWorkDate options:0];
NSLog(#"%#",[formatter stringFromDate:date]);
return date;
}
- (void)loadCollections
{
PHFetchOptions * options = [[PHFetchOptions alloc]init];
options.predicate = [NSComparisonPredicate predicateWithFormat:#"startDate > CAST(%d,\"NSDate\")",[self dateAddingDays2:-1 ToDate:[NSDate date]].timeIntervalSince1970];
PHFetchResult * result = [PHAssetCollection fetchMomentsWithOptions:options];
if(result != nil)
{
NSLog(#"%i",result.count);
for (int i = 0; i < result.count; i++) {
NSLog(#"%#",[result objectAtIndex:i]);
[moments addObject:[result objectAtIndex:i]];
}
}
}
So my problem is this, I need fetch fotos from one day ago, I can make this work!! any help will be appreciated.
This is the answer, basically I replaced
- (NSDate*)dateAddingDays:(NSInteger)days ToDate:(NSDate*)argDate
{
NSCalendar * gregorian = [NSCalendar currentCalendar];
NSDateFormatter * formatter = [[NSDateFormatter alloc]init];
[formatter setDateFormat:#"dd.MM.yyyy"];
NSString * dateString = [formatter stringFromDate:argDate];
NSDate * toWorkDate = [formatter dateFromString:dateString];
NSDateComponents *comps = [[NSDateComponents alloc] init];
[comps setDay:days];
NSDate *date = [gregorian dateByAddingComponents:comps toDate:toWorkDate options:0];
NSLog(#"%#",[formatter stringFromDate:date]);
return date;
}
by
- (NSDate*)yesterday
{
NSCalendar * gregorian = [NSCalendar currentCalendar];
return [gregorian startOfDayForDate:[gregorian dateByAddingUnit:NSCalendarUnitDay value:-1 toDate:[NSDate date] options:NSCalendarWrapComponents]];
}
and also replace this
options.predicate = [NSComparisonPredicate predicateWithFormat:#"startDate > CAST(%d,\"NSDate\")",[self dateAddingDays2:-1 ToDate:[NSDate date]].timeIntervalSince1970];
by this
options.predicate = [NSComparisonPredicate predicateWithFormat:#"(startDate > %#)",[self yesterday]];
and now is working!!! thanks to #Larme
Related
I have two times let say 8.40am and 4.00pm,
What i want to do is, want to check whether current time falls between given time or not ?
I have tried this code snippet but it is not working :(
can you please help me out where i am making mistake ?
NSDateComponents *components = [[NSCalendar currentCalendar] components:NSHourCalendarUnit | NSMinuteCalendarUnit | NSSecondCalendarUnit fromDate:[NSDate date]];
NSInteger currHr = [components hour];
NSInteger currtMin = [components minute];
NSString startTime = #"21:00";
NSString endTime = #"07:00";
NSArray *arr=[NSArray arrayWithObjects:startTime,endTime, nil];
int stHr = [[[[arr objectAtIndex:0] componentsSeparatedByString:#":"] objectAtIndex:0] intValue];
int stMin = [[[[arr objectAtIndex:0] componentsSeparatedByString:#":"] objectAtIndex:1] intValue];
int enHr = [[[[arr objectAtIndex:1] componentsSeparatedByString:#":"] objectAtIndex:0] intValue];
int enMin = [[[[arr objectAtIndex:1] componentsSeparatedByString:#":"] objectAtIndex:1] intValue];
int formStTime = (stHr*60)+stMin;
int formEnTime = (enHr*60)+enMin;
int nowTime = (currHr*60)+currtMin;
if(nowTime >= formStTime && nowTime <= formEnTime) {
NSLog(#"Btween......");
}
Thnaks in advance
EDIT:
NSDateComponents *openingTime = [[NSDateComponents alloc] init];
openingTime.hour = [timeA integerValue]; //8
openingTime.minute = [timeB integerValue]; //45
NSDateComponents *closingTime = [[NSDateComponents alloc] init];
closingTime.hour = [timeC integerValue]; //4
closingTime.minute = [timeD integerValue]; //43
NSDateFormatter *formatter = [[NSDateFormatter alloc]init];
[formatter setDateFormat:#"hh:mm"];
NSString *nowTimeString = [formatter stringFromDate:[NSDate date]];
NSDate *now = [formatter dateFromString:nowTimeString]; //3:30
NSDateComponents *currentTime = [[NSCalendar currentCalendar] components:NSCalendarUnitHour|NSCalendarUnitMinute|NSCalendarUnitSecond
fromDate:now];
NSMutableArray *times = [#[openingTime, closingTime, currentTime] mutableCopy];
[times sortUsingComparator:^NSComparisonResult(NSDateComponents *t1, NSDateComponents *t2) {
if (t1.hour > t2.hour) {
return NSOrderedDescending;
}
if (t1.hour < t2.hour) {
return NSOrderedAscending;
}
// hour is the same
if (t1.minute > t2.minute) {
return NSOrderedDescending;
}
if (t1.minute < t2.minute) {
return NSOrderedAscending;
}
// hour and minute are the same
if (t1.second > t2.second) {
return NSOrderedDescending;
}
if (t1.second < t2.second) {
return NSOrderedAscending;
}
return NSOrderedSame;
}];
if ([times indexOfObject:currentTime] == 1) {
NSLog(#"We are Open!");
} else {
NSLog(#"Sorry, we are closed!");
}
create date components for opening and closing time.
create date components with hour, minute, second from date to check
place opening, closing and current time in an array
sort array. if current time is at index 1, it lies between opening and closing time
NSDateComponents *openingTime = [[NSDateComponents alloc] init];
openingTime.hour = 8;
openingTime.minute = 40;
NSDateComponents *closingTime = [[NSDateComponents alloc] init];
closingTime.hour = 16;
closingTime.minute = 0;
NSDate *now = [NSDate date];
NSDateComponents *currentTime = [[NSCalendar currentCalendar] components:NSCalendarUnitHour|NSCalendarUnitMinute|NSCalendarUnitSecond
fromDate:now];
NSMutableArray *times = [#[openingTime, closingTime, currentTime] mutableCopy];
[times sortUsingComparator:^NSComparisonResult(NSDateComponents *t1, NSDateComponents *t2) {
if (t1.hour > t2.hour) {
return NSOrderedDescending;
}
if (t1.hour < t2.hour) {
return NSOrderedAscending;
}
// hour is the same
if (t1.minute > t2.minute) {
return NSOrderedDescending;
}
if (t1.minute < t2.minute) {
return NSOrderedAscending;
}
// hour and minute are the same
if (t1.second > t2.second) {
return NSOrderedDescending;
}
if (t1.second < t2.second) {
return NSOrderedAscending;
}
return NSOrderedSame;
}];
if ([times indexOfObject:currentTime] == 1) {
NSLog(#"We are Open!");
} else {
NSLog(#"Sorry, we are closed!");
}
Try this -
NSString *startTimeString = #"08:00 AM";
NSString *endTimeString = #"06:00 PM";
NSDateFormatter *formatter = [[NSDateFormatter alloc]init];
[formatter setDateFormat:#"hh:mm a"];
NSString *nowTimeString = [formatter stringFromDate:[NSDate date]];
int startTime = [self minutesSinceMidnight:[formatter dateFromString:startTimeString]];
int endTime = [self minutesSinceMidnight:[formatter dateFromString:endTimeString]];
int nowTime = [self minutesSinceMidnight:[formatter dateFromString:nowTimeString]];;
if (startTime <= nowTime && nowTime <= endTime)
{
NSLog(#"Time is between");
}
else {
NSLog(#"Time is not between");
}
-(int) minutesSinceMidnight:(NSDate *)date
{
NSDateComponents *components = [[NSCalendar currentCalendar] components:NSCalendarUnitHour | NSCalendarUnitMinute | NSCalendarUnitSecond fromDate:date];
return 60 * (int)[components hour] + (int)[components minute];
}
Check the screenshot -
I am trying to detect is a specific date is within the last 7 days (within the last week).
I have found a method to do that, but its eating my performance in a tableview (chat controller).
The code is posted below, and i know it can be done a LOT better, but i am running out of ideas. Does somebody have better approach? thanks!
The code:
NSDate *date = [[_messages objectAtIndex:indexPath.row] date];
NSString *lastMessageDateString = [[[NVDate alloc] initUsingDate:date] stringValueWithFormat:#"dd/MM/yy"];
NSString *todayDateString = [[[NVDate alloc] initUsingToday] stringValueWithFormat:#"dd/MM/yy"];
NSString *yesterdayDateString = [[[[NVDate alloc] initUsingToday] previousDay] stringValueWithFormat:#"dd/MM/yy"];
NSString *earlier2DaysDateString = [[[[NVDate alloc] initUsingToday] previousDays:2] stringValueWithFormat:#"dd/MM/yy"];
NSString *earlier3DaysDateString = [[[[NVDate alloc] initUsingToday] previousDays:3] stringValueWithFormat:#"dd/MM/yy"];
NSString *earlier4DaysDateString = [[[[NVDate alloc] initUsingToday] previousDays:4] stringValueWithFormat:#"dd/MM/yy"];
NSString *earlier5DaysDateString = [[[[NVDate alloc] initUsingToday] previousDays:5] stringValueWithFormat:#"dd/MM/yy"];
NSString *earlier6DaysDateString = [[[[NVDate alloc] initUsingToday] previousDays:6] stringValueWithFormat:#"dd/MM/yy"];
NSString *earlier7DaysDateString = [[[[NVDate alloc] initUsingToday] previousDays:7] stringValueWithFormat:#"dd/MM/yy"];
//return the time of the message since it is today
if ([lastMessageDateString isEqualToString:todayDateString]) {
return [SAD.myE.timeFormat stringFromDate:date];
}
//return the string "yesterday" of the message since it is yesterday
else if ([lastMessageDateString isEqualToString:yesterdayDateString]) {
return #"Yesterday";
}
//return the string of the actual day of the message since it is within last 7 days
else if ([lastMessageDateString isEqualToString:earlier2DaysDateString] ||
[lastMessageDateString isEqualToString:earlier3DaysDateString] ||
[lastMessageDateString isEqualToString:earlier4DaysDateString] ||
[lastMessageDateString isEqualToString:earlier5DaysDateString] ||
[lastMessageDateString isEqualToString:earlier6DaysDateString] ||
[lastMessageDateString isEqualToString:earlier7DaysDateString]) {
return [SAD.myE.dayFormat stringFromDate:date];
}
//return the string date since the message is olf
else {
return [SAD.myE.dateFormat stringFromDate:date];
}
EDIT
Thanks to #vikingosegundo i have tried to use his solution to implement this solution. He since then made a category that made it even easier that i will try and implement now. Just for the curious ones:
- (NSString *)stringForDate:(NSDate *)date {
NSDate *now = [NSDate date]; // now
NSDate *today;
[[NSCalendar currentCalendar] rangeOfUnit:NSDayCalendarUnit // beginning of this day
startDate:&today // save it here
interval:NULL
forDate:now];
NSDateComponents *comp = [[NSDateComponents alloc] init];
comp.day = 0;
NSDate * theDayToday = [[NSCalendar currentCalendar] dateByAddingComponents:comp toDate:today options:0];
if ([date compare:theDayToday] == NSOrderedDescending) {
return #"today";
}
comp.day = -1;
NSDate * yesterday = [[NSCalendar currentCalendar] dateByAddingComponents:comp toDate:today options:0];
if ([date compare:yesterday] == NSOrderedDescending) {
return #"yesterday";
}
comp.day = -7; // lets go 7 days back from today
NSDate * oneWeekBefore = [[NSCalendar currentCalendar] dateByAddingComponents:comp toDate:today options:0];
if ([date compare:oneWeekBefore] == NSOrderedDescending) {
return #"within 7 days";
} else {
return #"before 7 days";
}
}
-(BOOL) dayOccuredDuringLast7Days
{
NSDate *now = [NSDate date]; // now
NSDate *today;
[[NSCalendar currentCalendar] rangeOfUnit:NSDayCalendarUnit // beginning of this day
startDate:&today // save it here
interval:NULL
forDate:now];
NSDateComponents *comp = [[NSDateComponents alloc] init];
comp.day = -7; // lets go 7 days back from today
NSDate * oneWeekBefore = [[NSCalendar currentCalendar] dateByAddingComponents:comp
toDate:today
options:0];
if ([self compare: oneWeekBefore] == NSOrderedDescending) {
if ( [self compare:today] == NSOrderedAscending ) { // or now?
return YES;
}
}
return NO;
}
a complete command line example for last 7 days and yesterday. as category on NSDate
#import <Foundation/Foundation.h>
#interface NSDate (ExtendedComparions)
-(BOOL) dayOccuredDuringLast7Days;
-(BOOL) dayWasYesterday;
#end
#implementation NSDate (ExtendedComparions)
-(BOOL) _occuredDaysBeforeToday:(NSUInteger) nDaysBefore
{
NSDate *now = [NSDate date]; // now
NSDate *today;
[[NSCalendar currentCalendar] rangeOfUnit:NSDayCalendarUnit // beginning of this day
startDate:&today // save it here
interval:NULL
forDate:now];
NSDateComponents *comp = [[NSDateComponents alloc] init];
comp.day = -nDaysBefore; // lets go N days back from today
NSDate * before = [[NSCalendar currentCalendar] dateByAddingComponents:comp
toDate:today
options:0];
if ([self compare: before] == NSOrderedDescending) {
if ( [self compare:today] == NSOrderedAscending ) {
return YES;
}
}
return NO;
}
-(BOOL) dayOccuredDuringLast7Days
{
return [self _occuredDaysBeforeToday:7];
}
-(BOOL) dayWasYesterday
{
return [self _occuredDaysBeforeToday:1];
}
#end
int main(int argc, const char * argv[])
{
#autoreleasepool {
NSDate *now =[NSDate date];
NSDate *twoDaysBefore = [[NSCalendar currentCalendar] dateByAddingComponents:(
{
NSDateComponents *comps = [[NSDateComponents alloc] init];
comps.day = -2;
comps;
})
toDate:now
options:0];
if ([twoDaysBefore dayOccuredDuringLast7Days]) {
NSLog(#"last week");
} else {
NSLog(#"not last week");
}
if ([twoDaysBefore dayWasYesterday]) {
NSLog(#"yesteday");
} else {
NSLog(#"not yesterday");
}
}
return 0;
}
So I need to get the current event in the calendar. I.E - an event that started and did not end yet. I have written some code but it does not work.
Through debugging I noticed my oneDayAgo variable is nil and I do not understand why.
The oneWeekFromNow variable is good.
Here is the method I have written:
-(void)getCurrentEvent{
// Get appropriate calendar
[self.store requestAccessToEntityType:EKEntityTypeEvent
completion:^(BOOL granted, NSError *error) {
NSCalendar *calendar = [NSCalendar currentCalendar];
NSDateComponents *oneDayAgoComponents = [[NSDateComponents alloc] init];
oneDayAgoComponents.day -=1;
NSDate *oneDayAgo = [calendar dateByAddingComponents:oneDayAgoComponents
toDate:[NSDate date]
options:0];
NSDateComponents *oneWeekFromNowComponents = [[NSDateComponents alloc] init];
oneWeekFromNowComponents.week = 1;
NSDate *oneWeekFromNow = [calendar dateByAddingComponents:oneWeekFromNowComponents
toDate:[NSDate date]
options:0];
NSPredicate *predicate = [self.store predicateForEventsWithStartDate:oneDayAgo
endDate:oneWeekFromNow
calendars:nil];
NSMutableArray *currentEvens = [[NSMutableArray alloc]init];
// Fetch all events that match the predicate
[self.store enumerateEventsMatchingPredicate:predicate usingBlock:^(EKEvent *event, BOOL *stop) {
if (([event.startDate compare:[NSDate date]] == NSOrderedDescending) &&
([[NSDate date] compare:event.endDate] == NSOrderedDescending)) {
[currentEvens addObject:event];
}
}];
self.lblEvent.text = [NSString stringWithFormat:#"%#", currentEvens];
[self.view reloadInputViews];
}];
}
Try this instead:
NSDateComponents *oneDayAgoComponents = [[NSDateComponents alloc] init];
oneDayAgoComponents.day = -1;
Here is the corrected code that worked for me. I also needed to modify some other things:
-(void)getCurrentEvent{
// Get appropriate calendar
[self.store requestAccessToEntityType:EKEntityTypeEvent
completion:^(BOOL granted, NSError *error) {
NSCalendar *calendar = [NSCalendar currentCalendar];
NSDateComponents *oneDayAgoComponents = [[NSDateComponents alloc] init];
oneDayAgoComponents.day = -1;
NSDate *oneDayAgo = [calendar dateByAddingComponents:oneDayAgoComponents
toDate:[NSDate date]
options:0];
NSDateComponents *oneWeekFromNowComponents = [[NSDateComponents alloc] init];
oneWeekFromNowComponents.week = 1;
NSDate *oneWeekFromNow = [calendar dateByAddingComponents:oneWeekFromNowComponents
toDate:[NSDate date]
options:0];
NSPredicate *predicate = [self.store predicateForEventsWithStartDate:oneDayAgo
endDate:oneWeekFromNow
calendars:nil];
NSMutableArray *currentEvens = [[NSMutableArray alloc]init];
// Fetch all events that match the predicate
[self.store enumerateEventsMatchingPredicate:predicate usingBlock:^(EKEvent *event, BOOL *stop) {
if (([event.startDate compare:[NSDate date]] == NSOrderedAscending) &&
([[NSDate date] compare:event.endDate] == NSOrderedAscending)) {
[currentEvens addObject:event];
}
}];
NSString *currentEventsString = [[NSString alloc]init];
for (EKEvent *event in currentEvens) {
currentEventsString = [currentEventsString stringByAppendingString:event.title];
}
dispatch_async(dispatch_get_main_queue(), ^{
self.lblEvent.text = currentEventsString;
});
}];
}
I have a method that to create timestamp in long long integer format
EX: 1386752892
+ (NSNumber *)currentTimestampWithLongLongFormat
{
double timeStamp = ceil([[NSDate date] timeIntervalSince1970] * 1000);
NSNumberFormatter *formatter = [[NSNumberFormatter alloc] init];
[formatter setGeneratesDecimalNumbers:false];
NSNumber *timeNumber = [NSNumber numberWithDouble:timeStamp];
NSString *timeString = [formatter stringFromNumber:timeNumber];
// NSTimeInterval is defined as double
return [NSNumber numberWithLongLong:[timeString longLongValue]];
}
But this will generate 13 digitals number
EX: 1386752811802
How to fix the problem and generate the correct format of number?
int timestamp = [[NSDate date] timeIntervalSince1970];
Try this
/**
* #param nil
* #return current time in mili second
*
* Fetch the current time stamp
*/
-(NSString *)currentTimeStamp {
NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
[dateFormatter setDateFormat:#"yyyy-MM-dd HH:mm:ss"];
NSTimeZone *gmt = [NSTimeZone timeZoneWithName:#"GMT"];
[dateFormatter setTimeZone:gmt];
NSString *timeStamp1 = [dateFormatter stringFromDate:[NSDate date]];
NSDate *curdate = [dateFormatter dateFromString:timeStamp1];
double unix_timestamp = [curdate timeIntervalSince1970];
NSString *timeStamp = [NSString stringWithFormat:#"%f",unix_timestamp*1000];
return timeStamp;
}
+ (NSString*) dateFromString:(NSString*)aStr
{
NSDateFormatter *formater = [[NSDateFormatter alloc] init];
[formater setDateFormat:#"yyyy-MM-dd HH:mm"];
NSDate *date2 = [formater dateFromString:aStr];
[formater setDateFormat:#"d MMM,yyyy HH:mm"];
NSString *result = [formater stringFromDate:date2];
return result;
}
+ (NSString *)calculateTime:(NSString *)datetime :(NSString *)servertime
{
NSString *time;
NSDate *date1;
NSDate *date2;
{
NSDateFormatter *formatter = [[NSDateFormatter alloc] init];
[formatter setDateFormat:#"yyyy-MM-dd HH:mm:ss"];
date1 = [formatter dateFromString:datetime];
date2 = [formatter dateFromString:servertime];
}
NSCalendar *calendar = [NSCalendar currentCalendar];
NSDateComponents *differenceComponents = [calendar components:(NSDayCalendarUnit)
fromDate:date1
toDate:date2
options:0];
NSTimeInterval interval = [date1 timeIntervalSinceDate: date2];//[date1 timeIntervalSince1970] - [date2 timeIntervalSince1970];
int hour = interval / 3600;
int minute = (int)interval % 3600 / 60;
int seconds = (int)interval % 60;
hour=ABS(hour);
minute=ABS(minute);
seconds=ABS(seconds);
if ([differenceComponents day]>0) {
time= [NSString stringWithFormat:#"%ld %#", (long)[differenceComponents day],[NSString stringWithFormat:NSLocalizedString(#"daysago", nil)]];
}
else
{
if ([differenceComponents day] == 0) {
time= [NSString stringWithFormat:#"%ld %#", (long)[differenceComponents day],[NSString stringWithFormat:NSLocalizedString(#"dayago", nil)]];
if (hour>0) {
time= [NSString stringWithFormat:#"%d %#", ABS(hour),[NSString stringWithFormat:NSLocalizedString(#"hourago", nil)]];
}
else {
time= [NSString stringWithFormat:#"%d %#", ABS(hour),[NSString stringWithFormat:NSLocalizedString(#"hoursago", nil)]];
if (minute>0) {
time= [NSString stringWithFormat:#"%d %#", ABS(minute),[NSString stringWithFormat:NSLocalizedString(#"minuteago", nil)]];
}
else {
time= [NSString stringWithFormat:#"%d %#", ABS(minute),[NSString stringWithFormat:NSLocalizedString(#"minuteago", nil)]];
if (seconds>0) {
time= [NSString stringWithFormat:#"%d %#", ABS(seconds),[NSString stringWithFormat:NSLocalizedString(#"secondago", nil)]];
}
else {
time= [NSString stringWithFormat:#"%d %#", ABS(seconds),[NSString stringWithFormat:NSLocalizedString(#"secondsago", nil)]];
}
}
}
}
}
return time;
}
/// as per requirement we will use date formats
I need to sort an NSArray containing time NSString's such as,
NSMutableArray *times = [[NSMutableArray alloc]initWithObjects:#"09:00 AM",#"07:30 AM",#"06:45 PM",#"05:00 PM",#"12:45 AM",#"12:45 PM",#"01:00 AM",#"01:15 PM", nil];
What I need is to sort the array in ascending order of time.
Is there any way to do such a thing?
NSMutableArray *times = [[NSMutableArray alloc]initWithObjects:#"09:00 AM",#"07:30 AM",#"06:45 PM",#"05:00 PM",#"12:45 AM",#"12:45 PM",#"01:00 AM",#"01:15 PM", nil];
NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
[dateFormatter setDateFormat:#"hh:mm a"];
NSArray *sortedTimes = [times sortedArrayUsingComparator:^NSComparisonResult(NSString *obj1, NSString *obj2)
{
NSDate *date1 = [dateFormatter dateFromString:obj1];
NSDate *date2 = [dateFormatter dateFromString:obj2];
return [date1 compare:date2];
}];
optimized version:
NSMutableArray *times = [[NSMutableArray alloc]initWithObjects:#"09:00 AM",#"07:30 AM",#"06:45 PM",#"05:00 PM",#"12:45 AM",#"12:45 PM",#"01:00 AM",#"01:15 PM", nil];
NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
[dateFormatter setDateFormat:#"hh:mm a"];
NSMutableArray *dates = [NSMutableArray arrayWithCapacity:times.count];
for (NSString *timeString in times)
{
NSDate *date = [dateFormatter dateFromString:timeString];
[dates addObject:date];
}
[dates sortUsingSelector:#selector(compare:)];
NSMutableArray *sortedTimes = [NSMutableArray arrayWithCapacity:dates.count];
for (NSDate *date in dates)
{
NSString *timeString = [dateFormatter stringFromDate:date];
[sortedTimes addObject:timeString];
}
You can try this code:
NSDateFormatter *formatter = [[NSDateFormatter alloc] init];
[formatter setDateFormat:#"hh:mm a"];
[times sortUsingComparator:^NSComparisonResult(NSString* obj1, NSString *obj2) {
NSDate *firstDate = [formatter dateFromString:obj1];
NSDate *secondDate = [formatter dateFromString:obj2];
return [firstDate compare:secondDate];
}];
As these are strings it will be sored as
01:15, 12:25, 05:00....
And they are not either NSDate.
So you need to do is that Create a parallel array having NSDate from these strings, sort the array, and extract these values.
While implementing I solved it by novice-way
NSMutableArray *times = [[NSMutableArray alloc]initWithObjects:#"09:00 AM",#"07:30 AM",#"06:45 PM",#"05:00 PM",#"12:45 AM",#"12:45 PM",#"01:00 AM",#"01:15 PM", nil];
NSMutableArray *dates=[NSMutableArray new];
NSDateFormatter *dateFormatter=[NSDateFormatter new];
[dateFormatter setDateFormat:#"hh:mm a"];
for (NSString *stringDate in times) {
NSDate *date=[dateFormatter dateFromString:stringDate];
[dates addObject:date];
}
NSSortDescriptor *descriptor = [[NSSortDescriptor alloc] initWithKey:#"self" ascending:YES];
NSArray *descriptors = [NSArray arrayWithObject: descriptor];
NSArray *reverseOrder = [dates sortedArrayUsingDescriptors:descriptors];
[times removeAllObjects];
for (NSDate *date in reverseOrder) {
NSString *string=[dateFormatter stringFromDate:date];
[times addObject:string];
}
NSLog(#"%#",times);
For NSDate Comparison use this:
+ (BOOL)isDate:(NSDate *)date1 smallerThanAnotherDate:(NSDate *)date2
{
NSDate* enddate = date1;
NSDate* currentdate = date2;
NSTimeInterval distanceBetweenDates = [enddate timeIntervalSinceDate:currentdate];
double secondsInMinute = 60;
NSInteger secondsBetweenDates = distanceBetweenDates / secondsInMinute;
if (secondsBetweenDates <= 0)
return YES;
else
return NO;
}
So If you do not want to convert your hours to NSDate do this alone it works for me
NSArray *sortedTimes = [times sortedArrayUsingSelector:#selector(localizedStandardCompare:)];