Sorting the dates in an array? - ios

In my application I have an array of strings representing the dates in the Format MM/dd/YYYY
and below is the code I used to sort this array
NSDateFormatter *formatter =[[NSDateFormatter alloc]init];
[formatter setDateFormat:#"MM/dd/YYYY"];
NSLog(#" arr %#",arr);
[arr sortUsingComparator:^NSComparisonResult(id obj1, id obj2)
{
NSDate *date1=[formatter dateFromString:obj1];
NSDate *date2=[formatter dateFromString:obj2];
return [date1 compare:date2];
}];
NSLog(#" arr %#",arr);
below is the output of nslog
2013-04-08 17:23:48.112 SEEMR[2792:c07] arr (
"02/18/2013",
"02/16/2013",
"02/14/2013",
"01/16/2013",
"02/13/2013",
"03/16/2013"
)
2013-04-08 17:24:07.662 SEEMR[2792:c07] arr (
"02/18/2013",
"02/16/2013",
"02/14/2013",
"01/16/2013",
"02/13/2013",
"03/16/2013"
)
But it is not sorting as expected so help me peers

When using NSDateFormatter, always test if your formatting string is correct. Yours isn't. It should be MM/dd/yyyy (the case is important).
In other words, since your formatter works incorrectly, all dateFromString: return nil and you are always comparing nil with a nil, which returns 0.
Saving your dates as a NSDate instances would make your life easier. In general, it's better to convert the date into NSString only if you are presenting it to the user or sending it to some other application (e.g. web service).

You can do something like this:
NSSortDescriptor* sortByDate = [NSSortDescriptor sortDescriptorWithKey:#"date property name" ascending:YES];
[mutableArray sortUsingDescriptors:[NSArray arrayWithObject:sortByDate]];
Hope it helps!

Related

How to Sort array based on date and time

i have date string in form of "yyyy-MM-dd HH:mm" i have some 100 obhjects in an array with different date and time.now my question is how to sort this array based on time and date, i tried in many ways but no use .can any one help me .thanks in advance
used this method for sort an array.
NSSortDescriptor *sortDescriptor = [NSSortDescriptor sortDescriptorWithKey:#"date" ascending:NO];
NSArray *sortedArray = [detailsArray sortArrayUsingDescriptors:#[sortDescriptor]];
May be help for you
If you have an array of strings, take advantage of your date format and just sort it lexically.
NSArray* sorted = [dates sortedArrayUsingComparator:^(NSString* a, NSString* b) {
return [a compare:b];
}];
If you actually have an array of NSDate objects, use the NSDate compare functions, using almost identical code (compare: works to compare two homogenous data types in many cases)
NSArray* sorted = [dates sortedArrayUsingComparator:(NSDate* a, NSDate* b) {
return [a compare:b];
}];
With the simplicity of the comparator, you can actually just use the selector directly:
NSArray* sorted = [dates sortedArrayUsingSelector:#selector(compare:)];

Sorting NSMutableArray based on the content of its objects

I have an NSMutableArray called self.objectArray, that contains custom objects. Each object holds an NSDictionary and two other string objects. Actually I need to work only with the dictionary. Every dictionary contains a key named keyDate which holds an NSString that look like this: MM/dd/yy HH:mm:ss.
I would like to sort the array based on their keyDate. The object with the oldest date should be the first object and so on. I've found some questions, that looked helpful and I could create the code that you can see below, but I get an error everytime I run it. As I think NSSortDescriptor won't be the right tool since my keys aren't key value compliant.
PNMessage 0x125c0590> valueForUndefinedKey:]: this class is not key value coding-compliant for the key keyDate.'
NSSortDescriptor *dateDescriptor = [NSSortDescriptor
sortDescriptorWithKey:#"keyDate"
ascending:YES];
NSArray *sortDescriptors = [NSArray arrayWithObject:dateDescriptor];
NSArray *sortedEventArray = [self.objectArray
sortedArrayUsingDescriptors:sortDescriptors];
self.finallySorted = [sortedEventArray mutableCopy];
If it's possible I would do it with sort descriptor, however I think there should be some other options, but can't figure out its proper implementation.
So I can also catch every object's keyDate with a for loop, but don't know how can I sort them based on the value. I would really appreciate if somebody could show me the right way.
for(PNMessage *mg in self.objectArray)
{
NSLog(#" test log %#", mg.message[#"keyDate"]);
}
I already checked this answer:
How to sort an NSMutableArray with custom objects in it?
but the structure of my object is different.
My first code based on this question, but it doesn't worked.
How to sort an NSMutableArray with custom objects in it?
UPDATE: my try based on Kaan's answer (doesn't works yet)
static NSDateFormatter *formatter = nil;
if(!formatter) {
formatter = [[NSDateFormatter alloc] init];
[formatter setDateFormat:#"MM/dd/yy HH:mm:ss"];
}
NSArray *sortedArray = [self.object sortedArrayUsingComparator:^NSComparisonResult(PNMessage *obj1, PNMessage *obj2) {
NSString *date1String = obj1.message[#"keyDate"];
NSString *date2String = obj1.message[#"keyDate"];
NSDate *date1 = [formatter dateFromString:date1String];
NSDate *date2 = [formatter dateFromString:date2String];
if ( date1 < date2 ) {
return (NSComparisonResult)NSOrderedAscending;
} else if ( date1 > date2 ) {
return (NSComparisonResult)NSOrderedDescending;
}
return (NSComparisonResult)NSOrderedSame;
}];
I would consider using the sortedArrayUsingComparator method
Assuming your custom class is called PNMessage:
static NSDateFormatter *formatter = nil;
if(!formatter) {
formatter = [[NSDateFormatter alloc] init];
[formatter setFormat:#"MM/dd/yy HH:mm:ss"];
}
NSArray *sortedArray = [self.objectArray sortedArrayUsingComparator:^NSComparisonResult(PNMessage *obj1, PNMessage *obj2) {
NSString *date1String = obj1[#"keyDate"];
NSString *date2String = obj1[#"keyDate"];
NSDate *date1 = [formatter dateFromString:date1String];
NSDate *date2 = [formatter dateFromString:date2String];
return [date1 compare:date2];
}];
Tip: If you decide on following this, make sure you declare your NSDateFormatter instance as static outside of the sorting body, since allocating Formatters in iOS can be very expensive and cause serious performance penalties.

Converting NSString to NSDate with different timezones, for use with a UIDatePicker

I am looking to convert a NSString to an NSDate and would just like to ask a few questions about this.
The purpose of the conversion is to take a section header in a table view which is a string derived from an NSDate, and to pass it back to a UIDatePicker, so that the date picker can use that date in the string.
I've been reading some posts about this and there are tons of formats to work through.
My string date format is in the form:
March 10, 2014 for American formats and 10 March 2014 for UK formats.
What would I need to do to:
1) Get that date to translate over to the UIDatePicker appropriately
2) Work with different country formats so that the date picker is updated for UK and US users.
NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
[dateFormatter setDateFormat:#"d-MMMM-YYYY"];
NSDate *dateFromString = [[NSDate alloc] init];
dateFromString = [dateFormatter dateFromString:sectionTitle];
dateFromString is currently null.
I've been looking at https://developer.apple.com/library/ios/documentation/Cocoa/Conceptual/DataFormatting/Articles/dfDateFormatting10_4.html , Converting NSString to NSDate (and back again) and http://waracle.net/iphone-nsdateformatter-date-formatting-table/ but am not sure how to proceed.
Any assistance would be appreciated on this
I know this isn't directly answering the question, but it makes several of the above comments make more sense:
How to create the data source structure for a table view:
NSMutableArray* sections = [NSMutableArray array];
for (<each section>) {
NSMutableDictionary* section = [NSMutableDictionary dictionary];
[section setObject:sectionTitle forKey:#"title"];
[section setObject:sectionNSDate forKey:#"date"];
[section setObject:otherStuff forKey:#"other_stuff"];
NSMutableArray* rows = [NSMutableArray array];
for (<each row>) {
NSMutableDictionary* row = [NSMutableDictionary dictionary];
[row setObject:rowTitle forKey:#"title"];
[row setObject:image forKey:#"image"];
[rows addObject:row];
}
[section addObject:rows forKey:#"rows"];
[sections addObject:section];
}
It's easy to keep track of & update section and row data, the number of sections and number of rows methods virtually write themselves, you don't need to re-derive data if something is scrolled away and comes back (since you can cache it in the dictionary).

sortedArrayUsingComparator not working for array in IOS?

hello i want to sort the array with oldest to latest date. it works perfect for the small data. but when the data is large not getting the perfect soreted array.
here is my code
-(NSMutableArray *)sortArrayOldestTonewest:(NSMutableArray *)arr{
NSArray *sortedArray;
NSMutableArray *arrResponse=[NSMutableArray arrayWithArray:arr];
sortedArray = [arrResponse sortedArrayUsingComparator:^(id a,id b) {
NSString *str1 = [a valueForKey:#"CardExpiryDate"];
NSString *str2 = [b valueForKey:#"CardExpiryDate"];
NSDate *date1=[Utility dateFromString:str1 withFormat:#"dd/mm/yyyy"];
NSDate *date2=[Utility dateFromString:str2 withFormat:#"dd/mm/yyyy"];
return [date1 compare:date2];
}];
NSMutableArray *arrResult=[[NSMutableArray alloc]initWithArray:sortedArray];
return arrResult
;
}
what i am doing wrong.
please help.
Your date format is wrong, it should be #"dd/MM/yyyy".
"MM" is for month, "mm" is for minutes.
It must be pure coincidence that your results were correct for small datasets.

How to sort NSMutableArray of date objects

I'm doing some small work on sorting the date strings in the NSMutableArray, i'm getting the array from the sqlite db.
If you print the array it is showing like this
date strings are (
"2011-05-01",
"2011-02-01",
"2012-01-08",
"2012-05-08",
"2010-01-09
)
I want to show the dates in ascending order. Please help me out guys..... I'm newbie to objc..
First you should convert all date Strings (which is NSString) objects to NSDate objects and then sort these dateObjects.
I believe you have dateArray containing all those strings.
NSSortDescriptor *descriptor = [[NSSortDescriptor alloc] initWithKey:#"self"
ascending:NO];
NSArray *descriptors = [NSArray arrayWithObject:descriptor];
NSArray *reverseOrder = [dateArray sortedArrayUsingDescriptors:descriptors];
OR
NSArray *reverseOrderUsingComparator = [dateArray sortedArrayUsingComparator:
^(id obj1, id obj2) {
return [obj2 compare:obj1];
}];
If your dates are really strings in the format YYYY-mm-dd, as in your question, then this will sort them in ascending order:
[arrayOfDates sortUsingSelector:#selector(compare:)];
That will also work if your dates are actually NSDate objects.
If you want to create a sorted copy of the array:
NSArray *sortedArray = [arrayOfDates sortedArrayUsingSelector:#selector(compare:)];
Sorting should be done, imo, by the database, in general. sqlite3 does support order by.

Resources