NSCalendar добавить пол месяца к NSDate - PullRequest
1 голос
/ 09 апреля 2011

Я пытаюсь определить график платежей, когда существует 24 платежа в год (т.е. дважды в месяц).Платежи не всегда будут 1-м и 15-м.Я должен начать с данного дня, а затем рассчитывать два раза в месяц, начиная с этого момента.

NSCalendar и NSDateComponents имеют возможность добавлять целые дни, недели, месяцы и т. Д. Что мне действительно нужно сделать, этобыть в состоянии добавить 0,5 месяца, но он обрабатывает только целые числа.Я не могу просто добавить 15 дней, потому что месяцы имеют разное количество дней (что является частью магии, которую NSCalendar должен обрабатывать для нас).Первый платеж за месяц должен производиться в день, скажем, месяц, поэтому, если платежи начинаются 8-го числа, то каждый нечетный платеж должен быть 8-го числа, а каждый четный платеж - 8-го + полугодия.Вот тут-то и возникают сложности. Я полагаю, что, по крайней мере, я могу использовать добавление за месяц, чтобы получить все нечетные платежи.Получение даты для этих четных платежей - трудная часть.

Есть ли способ добавить пол месяца через NSCalendar, который я пропускаю?Если нет, то есть ли у вас элегантное решение для создания этих 24 дат в год?

Ответы [ 2 ]

2 голосов
/ 09 апреля 2011

Нет, вы должны сами рассчитать полугодовой расчет.Просто для удовольствия я написал для вас следующее.Наслаждайтесь.

- (NSArray *)createPaymentScheduleWithStartDate:(NSDate *)startDate numberOfPayments:(NSUInteger)payments {
    NSUInteger count = 0;
    NSCalendar *cal = [NSCalendar currentCalendar];
    NSMutableArray *schedule = [NSMutableArray arrayWithCapacity:payments];

    // break down the start date for our future payments
    unsigned unitFlags = NSYearCalendarUnit | NSMonthCalendarUnit |  NSDayCalendarUnit 
            | NSTimeZoneCalendarUnit | NSHourCalendarUnit | NSMinuteCalendarUnit;
    NSDateComponents *comps = [cal components:unitFlags fromDate:startDate];
    NSInteger month = [comps month];
    NSInteger day = [comps day];
    NSInteger year = [comps year];


    // For simplicity sake, adjust day larger than 28
    // this way we don't have to test each time we create a date
    // if it valid.
    if (day > 28)
        day = 28;

    // NSDate *a = startDate;
    // because we want all payments to have the same time
    // create the first again
    NSDate *a = [cal dateFromComponents:comps];

    do {
        month++;
        if (month > 12) {
            year++;
            month = 1;
        }

        // create the next month payment date
        comps.month = month;
        comps.day = day;
        comps.year = year;
        NSDate *b = [cal dateFromComponents:comps];

        // find the middle date
        NSTimeInterval m = [b timeIntervalSinceDate:a];
        NSDate *c = [a dateByAddingTimeInterval:m / 2];

        // add dates to our schedule array
        [schedule addObject:a];
        [schedule addObject:c];
        count += 2;

        // adjust to next group of payments
        a = b;

    } while (count < (payments + 5));



    // because we add two payments at a time,
    // we have to adjust that extra payment
    if ([schedule count] > payments) {
        // create range of our excess payments
        NSRange range = NSMakeRange(payments, [schedule count] - payments);
        [schedule removeObjectsInRange:range];
    }

    NSLog(@"Schedule: %@", schedule);
    return [NSArray arrayWithArray:schedule];
}
2 голосов
/ 09 апреля 2011

Что ж, если вы можете вычислить дату, которая составляет 1 месяц от даты начала, вычисление за полмесяца происходит только на одно деление:

NSTimeInterval oneMonthInterval = [oneMonthLater timeIntervalSinceDate:startDate];
NSTimeInterval halfMonthInterval = oneMonthInterval / 2.0;
NSDate *halfAMonthLater = [startDate dateByAddingTimeInterval:halfMonthInterval];
...