dateByAddingComponents и получение разницы дат с помощью NSDateComponents

У меня проблемы с добавлением значений к датам, а также с получением различий между датами. Вычисленные даты и компоненты неверны.

Итак, для добавления, если я добавляю 1,5 месяца, я получаю только 1 месяц, однако, если я добавляю любое целое число, т.е. (1, 2, 3 и т. д.), оно вычисляется правильно.

Float32 addAmount = 1.5;

NSDateComponents *components = [[[NSDateComponents alloc] init] autorelease];
[components setMonth:addAmount];

NSCalendar *gregorian = [[[NSCalendar alloc] initWithCalendarIdentifier:NSGregorianCalendar] autorelease];
 [gregorian setTimeZone:[NSTimeZone timeZoneWithName:@"UTC"]];

 NSDate *newDate2 = [gregorian dateByAddingComponents:components toDate:Date1 options:0];

Теперь для разницы, если у меня есть дата, которая была добавлена ​​​​ровно с одним годом (почти тот же код, что и выше), она добавляется правильно, но когда разница вычисляется, я получаю 0 лет, 11 месяцев и 30 дней.

NSDate *startDate = Date1;
NSDate *endDate = Date2;

NSCalendar *gregorian = [[NSCalendar alloc]
          initWithCalendarIdentifier:NSGregorianCalendar];
[gregorian setTimeZone:[NSTimeZone timeZoneWithName:@"UTC"]];

NSUInteger unitFlags = NSYearCalendarUnit | NSMonthCalendarUnit | NSDayCalendarUnit;

NSDateComponents *components = [gregorian components:unitFlags
              fromDate:startDate
                toDate:endDate options:0];

NSInteger years = [components year];
NSInteger months = [components month];
NSInteger days = [components day];

Что я делаю не так? Также я добавил константу kCFCalendarComponentsWrap в опции как для добавления, так и для разностных функций, но без разницы.

Спасибо


person Rob    schedule 25.03.2010    source источник


Ответы (2)


Итак, для добавления, если я добавляю 1,5 месяца, я получаю только 1 месяц, однако, если я добавляю любое целое число, т.е. (1, 2, 3 и т. д.), оно вычисляется правильно.

Метод setMonth: в NSDateComponents принимает NSInteger, а не число с плавающей запятой. Таким образом, поведение правильное, так как оно просто усекает 1,5 до 1.

Теперь для разницы, если у меня есть дата, которая была добавлена ​​​​ровно с одним годом (почти тот же код, что и выше), она добавляется правильно, но когда разница вычисляется, я получаю 0 лет, 11 месяцев и 30 дней.

Если вы не покажете код того, как создаются ваши переменные Date1 и Date2, нет реального способа сказать это.

(Вы также приводите к утечке памяти выше; всегда сопоставляйте alloc с release/autorelease. И старайтесь не давать своим переменным заглавные буквы, поскольку в соответствии со стилем это следует делать только для имен классов)

person Shaggy Frog    schedule 25.03.2010
comment
Утечек памяти не заметил, спасибо, что заметили. Переменные даты обычно создаются из uidatepicker с таким кодом, как date1 = self.dob.date; Где dob — имя средства выбора даты. Вы абсолютно правы насчет имен переменных, я изменил их для публикации, не задумываясь о регистре. - person Rob; 25.03.2010

Наконец-то я обнаружил проблему с разницей в дате: когда я сохранял ее в БД, я использовал timeintervalsince1970 с двойным значением, но при его заполнении и установке для средства выбора даты я использовал тип столбца int.

Спасибо Shaggy Frog за то, что направил меня в правильном направлении.

person Rob    schedule 25.03.2010