ios - get in between dates (in actual date, not number of days)

浪尽此生 提交于 2019-11-30 10:39:29
NSString *start = @"2010-09-01";
NSString *end = @"2010-12-05";

NSDateFormatter *f = [[NSDateFormatter alloc] init];
[f setDateFormat:@"yyyy-MM-dd"];
NSDate *startDate = [f dateFromString:start];
NSDate *endDate = [f dateFromString:end];

NSMutableArray *dates = [@[startDate] mutableCopy];


NSCalendar *gregorianCalendar = [[NSCalendar alloc] initWithCalendarIdentifier:NSGregorianCalendar];
NSDateComponents *components = [gregorianCalendar components:NSDayCalendarUnit
                                                    fromDate:startDate
                                                      toDate:endDate
                                                     options:0];

for (int i = 1; i < components.day; ++i) {
    NSDateComponents *newComponents = [NSDateComponents new];
    newComponents.day = i;

    NSDate *date = [gregorianCalendar dateByAddingComponents:newComponents 
                                                      toDate:startDate 
                                                     options:0];
    [dates addObject:date];
}

[dates addObject:endDate];

The array dates now contains the list of dates between startDate and endDate, including those, for midnight in the timezone of the device.
Note, that on some timezones this might cause trouble, as the switch from and to Daylight Saving Time might occur at that moment, see WWDC 2011 Video "Session 117 - Performing Calendar Calculations" for further information. One trick is to shift the hour to a save time, i.e. noon, do the calculation and than subtract 12 hours.

Ok, you're most of the way there. You have a date formatter that converts the date strings to NSDates. You have the number of days between the dates. Now you need to loop from the start date for that many days, adding a variable number of days to the start date.

The method you need is dateByAddingComponents:toDate:options:.

Something like this (goes immediately after your code) :

  int days = components.day;

  NSDateComponents *daysToAdd = [[NSDateComponents alloc] init];
  for (int count = 0; count <= days; count++)
  {
    daysToAdd.day = count;
    NSDate *loopDate = [gregorianCalendar dateByAddingComponents: daysToAdd
                                                         toDate: startDate
                                                        options: 0 ];
    NSLog(@"Day %d = %@", count+1, [f stringFromDate: loopDate]);
  }

I haven't tested it, but that's the basic idea...

The code above should include both the start and end dates.

If you don't want to include the start date, make the loop start at count = 1 instead of count = 0.

If you don't want to include the end date, make the loop check count < days.

A little late but found a fix to the 'TIMEZONE' time issue that vikingosegundo talked about in his answer. I simply converted the NSDate to an NSString by calling a stringFromDate method on the formatter *f in your for loop...

for (int i = iStart; i < components.day; ++i) {
    NSDateComponents *newComponents = [NSDateComponents new];
    newComponents.day = i;
    newComponents.hour = 0;
    newComponents.minute = 0;
    newComponents.second = 0;

    NSDate *date = [gregorianCalendar dateByAddingComponents:newComponents
                                                      toDate:startDate
                                                     options:0];
    // THIS IS THE CODE I ADDED TO MINE //
    // convert NSDate to string calling on *f (NSDateformatter)
    NSString *string = [f stringFromDate:date];
    // split the string to separate year, month, etc... 
    NSArray *array = [string componentsSeparatedByString:@"-"];
    // create second NSString withFormat and only add the variable from the date that you find pertinent 
    NSString *sDateNew = [NSString stringWithFormat:@"%@-%@-%@",array[0],array[1],array[2]];
    // then simply add the sDateNew string to dates array
    [dates addObject:sDateNew];
}

I think this should be put into the comment section of your answer vikingsegundo but it would not let me.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!