Naresh
Naresh

Reputation: 17902

How to group the dates from array?

My date formate is “2019-12-03T05:58:11.317Z” like this. I want to group the same date elements. And i can create UITableView sections based on dates. This is array i have three different dates so i want to create 3 sections. Here the problem is newArrayList not saving all the elements.

        NSMutableArray * arrayList;
        NSMutableArray *newArrayList;
        //This is my date array
        arrayList = [[NSMutableArray alloc] initWithObjects:@“2019-12-03T05:58:11.317Z”, @“2019-12-03T05:58:10.317Z”, @“2019-12-03T05:58:01.317Z”, @“2019-12-03T05:55:12.448Z”, @“2019-12-03T05:48:11.317Z”, @“2019-12-03T05:28:11.317Z”, @“2019-12-03T05:11:24.004Z”, @“2019-12-03T05:28:11.317Z”, @“2019-12-03T05:55:12.965Z”, @“2019-12-02T15:09:35.408Z”, @“2019-12-02T15:09:38.187Z”, @“2019-12-02T15:43:02.118Z”, @“2019-12-02T15:44:09.344Z”, @“2019-12-02T17:07:55.038Z”, @“2019-12-02T16:42:16.649Z”, @“2019-12-01T16:42:16.649Z”, nil];

        newArrayList = [[NSMutableArray alloc]init];//Here I want to same date elements 

            NSDate *fromDate;
            NSMutableArray *tempArray = [[NSMutableArray alloc] init];
            for (int i=0; i<arrayList.count; i++) {
                NSDate *dt1 = fromDate;
                NSDate *dt2 = [self getLocalDateTimeFromUTC2:[arrayList objectAtIndex:i]];
                if (i != 0) {
                    if ([self isSameDay:dt1 otherDay:dt2] == YES) {
                        [tempArray addObject:t];
                    } else {
                        [newArrayList addObject:tempArray];
                    //  [tempArray removeAllObjects];
                    }
                }
                fromDate = dt2;
            }

//To get required date formate
-(NSDate *)getLocalDateTimeFromUTC2:(NSString *)strDate
{

// create dateFormatter with UTC time format
NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
[dateFormatter setDateFormat:@"yyyy-MM-dd'T'HH:mm:ss.SSSZZZZ"]; //@"yyyy-MM-dd'T'HH:mm:ss.SSSZZZZ"
[dateFormatter setTimeZone:[NSTimeZone timeZoneWithAbbreviation:@"UTC"]];
//    NSLog(@"%@", t.dateAndTime); //2019-12-02T15:09:38.187Z
NSDate *date = [dateFormatter dateFromString:strDate]; // create date from string

// change to a readable time format and change to local time zone
[dateFormatter setDateFormat:@"dd-MM-yyyy"];
[dateFormatter setTimeZone:[NSTimeZone localTimeZone]];
NSString *timestamp = [dateFormatter stringFromDate:date];

NSDateFormatter *dateFormat = [[NSDateFormatter alloc] init];
[dateFormat setDateFormat:@"dd-MM-yyyy"];
[dateFormat setTimeZone:[NSTimeZone localTimeZone]];
NSDate *date2 = [dateFormat dateFromString:timestamp];
//    NSLog(@"%@", date2);

return date2;
}

//To compare two dates
- (BOOL)isSameDay:(NSDate*)date1 otherDay:(NSDate*)date2 {

NSCalendar* calendar = [NSCalendar currentCalendar];
unsigned unitFlags = NSCalendarUnitYear | NSCalendarUnitMonth |  NSCalendarUnitDay;
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];
}

Upvotes: 0

Views: 104

Answers (3)

ingconti
ingconti

Reputation: 11646

some notes: 1) do not keep dates as strings, for many reasons: a) Date use less memory b) you can compare and sort using but in functions that take in account timezones and leaps.

2) do not create formatters in every place (i.e. put therm out of for) as per Apple:

https://developer.apple.com/library/archive/documentation/Cocoa/Conceptual/DataFormatting/Articles/dfDateFormatting10_4.html#//apple_ref/doc/uid/TP40002369-SW10

Upvotes: 0

Nick
Nick

Reputation: 875

Try this:

NSMutableDictionary *dictByDate = [NSMutableDictionary new];
NSMutableArray *newArr = [NSMutableArray new] ;

for(NSString *strDate in arrayList)
{

    // convert date to proper formate (if needed)

    NSDateFormatter *format = [[NSDateFormatter alloc] init];
    [format setDateFormat:@"yyyy-MM-dd'T'HH:mm:ss.SSSZZZZ"];
    NSDate *dateNew = [format dateFromString:strDate];
    [format setDateFormat:@"MMMM-dd-yyyy"];
    NSString *finalDateString = [format stringFromDate:dateNew];

    NSLog(@"%@",finalDateString) ;

    NSMutableArray *arrWithSameDate = dictByDate[finalDateString];
    if(! arrWithSameDate)
    {
        arrWithSameDate = [NSMutableArray new];
        dictByDate[finalDateString] = arrWithSameDate;
    }
    [arrWithSameDate addObject: strDate];

}

[newArr addObjectsFromArray:[dictByDate allValues]] ;

NSLog(@"group data: %@", newArr);

Upvotes: 2

dahiya_boy
dahiya_boy

Reputation: 9503

I'm doing in swift, hope you will manage in obj-c


  1. Assuming you have below data

    let arrDates = [  "2019-12-03T05:58:11.317Z ",   "2019-12-03T05:58:10.317Z ",   "2019-12-03T05:58:01.317Z ",   "2019-12-03T05:55:12.448Z ",   "2019-12-03T05:48:11.317Z ",   "2019-12-03T05:28:11.317Z ",   "2019-12-03T05:11:24.004Z ",   "2019-12-03T05:28:11.317Z ",   "2019-12-03T05:55:12.965Z ",   "2019-12-02T15:09:35.408Z ",   "2019-12-02T15:09:38.187Z ",   "2019-12-02T15:43:02.118Z ",   "2019-12-02T15:44:09.344Z ",   "2019-12-02T17:07:55.038Z ",   "2019-12-02T16:42:16.649Z ",   "2019-12-01T16:42:16.649Z "]
    
  2. Make group of date

    let dictGroupDate = Dictionary(grouping: arrDates) { (strdate) -> String in
    let df = DateFormatter()
    df.dateFormat = "yyyy-MM-dd'T'HH:mm:ss.SSSZZZZ"
    let date = df.date(from: strdate)
    df.dateFormat = "yyyy-MM-dd"
    return df.string(from: date!)
    }
    
  3. Get all section dates and sort them

    let arrDateKey = Array(dictGroupDate.keys).sorted { (strdate1, strdate2) -> Bool in
    let df = DateFormatter()
    df.dateFormat = "yyyy-MM-dd"
    let date1 = df.date(from: strdate1)
    let date2 = df.date(from: strdate2)
    
    return date1!.compare(date2!)  == .orderedAscending
    }
    
  4. sort time for every date and create new dict

     var newGroupedDates = [String : [String]]()
    
    for strKey in arrDateKey {
    let sortedTime = dictGroupDate[strKey]?.sorted(by: { (strdate1, strdate2) -> Bool in
        let df = DateFormatter()
        df.dateFormat = "yyyy-MM-dd'T'HH:mm:ss.SSSZZZZ"
        let date1 = df.date(from: strdate1)
        let date2 = df.date(from: strdate2)
    
        return date1!.compare(date2!)  == .orderedAscending
    
      })
    
    newGroupedDates[strKey] = sortedTime!
    }
    
  5. Show data in UITABLEVIEW

    // NumberOfSections
    arrDateKey.count
    
    //NumberOfRows
    let key = arrDateKey[indexPath.section]
    newGroupedDates[key]?.count
    
    // CellForRow
    // To get correct date and Time
    
    let key = arrDateKey[indexPath.section]
    let item = newGroupedDates[key]![indexPath.row]
     // Now item is the date string, and do whatever you wanted to do.
    

Output

Final newGroupedDates

["2019-12-03": ["2019-12-03T05:11:24.004Z ", "2019-12-03T05:28:11.317Z ", "2019-12-03T05:28:11.317Z ", "2019-12-03T05:48:11.317Z ", "2019-12-03T05:55:12.448Z ", "2019-12-03T05:55:12.965Z ", "2019-12-03T05:58:01.317Z ", "2019-12-03T05:58:10.317Z ", "2019-12-03T05:58:11.317Z "], "2019-12-02": ["2019-12-02T15:09:35.408Z ", "2019-12-02T15:09:38.187Z ", "2019-12-02T15:43:02.118Z ", "2019-12-02T15:44:09.344Z ", "2019-12-02T16:42:16.649Z ", "2019-12-02T17:07:55.038Z "], "2019-12-01": ["2019-12-01T16:42:16.649Z "]]

In case, I missed something then comment me.

Upvotes: 1

Related Questions