NSDate - год назад, дилемма - PullRequest
       5

NSDate - год назад, дилемма

5 голосов
/ 19 января 2011

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

Учитывая дату, скажем January 17, 2011, я пытаюсь определить день, который соответствует этой дате год назад. Итак, January 17, 2011 - понедельник, а год назад этот день упал на January 18, 2010 (также и на понедельник). Оказывается, что January 18, 2010 - это 354 дня до January 17, 2011. Первоначально я думал просто вычесть 365 дней для високосного года и 366 дней для високосного года, но если вы сделаете это в этом случае, вы получите January 17, 2010, то есть воскресенье, а не понедельник. *

Итак, в Objective-C с NSDate и NSCalendar, как я мог бы реализовать такую ​​функцию, как:

-(NSDate *)logicalOneYearAgo:(NSDate *)from {
}

Другими словами, n-й «день недели» n-го месяца (где «день недели» - понедельник, вторник или среда и т. Д.)

Ответы [ 5 ]

22 голосов
/ 19 января 2011

Вы используете NSDateComponents следующим образом:

- (NSDate *)logicalOneYearAgo:(NSDate *)from {

    NSCalendar *gregorian = [[[NSCalendar alloc] initWithCalendarIdentifier:NSGregorianCalendar] autorelease];

    NSDateComponents *offsetComponents = [[[NSDateComponents alloc] init] autorelease];
    [offsetComponents setYear:-1];

    return [gregorian dateByAddingComponents:offsetComponents toDate:from options:0];

}
11 голосов
/ 15 мая 2012

Это описано в Руководстве по программированию даты и времени в разделе Календарные вычисления, Добавление компонентов к дате

В частности, интересующий метод dateByAddingComponents: toDate: options .

Используя пример Apple в качестве основы, чтобы вычесть один год из текущей даты, вы должны сделать следующее:

NSDate *today = [[NSDate alloc] init];
NSCalendar *calendar = [[NSCalendar alloc] initWithCalendarIdentifier:NSGregorianCalendar];

/*
  Create a date components to represent the number of years to add to the current date.
  In this case, we add -1 to subtract one year.     
*/

NSDateComponents *addComponents = [[NSDateComponents alloc] init];
addComponents.year = - 1;

return [calendar dateByAddingComponents:addComponents toDate:today options:0];
3 голосов
/ 19 января 2011

Я не могу гарантировать, что это самый эффективный способ, но вы можете сделать это, используя NSCalendar и NSDateComponents. Передайте ваш NSDate экземпляр в [yourCalendar components:yourComponents fromDate:yourDate], вычтите год из компонентов, а затем используйте [yourCalendar dateFromComponents:yourComp].

Извините, что не предоставил полный код, но я давно работал с этими методами и не хочу давать вам код, который не будет работать.

0 голосов
/ 16 июня 2011

выписка 1 год.Затем вычтите 1 день, пока вы не закончите тем же днем ​​недели, который вы хотите.

Каждый год "дни недели" возвращаются на 1 день, кроме случаев, когда между ними 29 февраля, они возвращаются на 2 дня.

Это потому, что год составляет 52 недели + 1 день (+2 для високосных лет).

Так что, если вы будете применять эту логику бесконечно, вы в конечном итоге, год за годом, будете иметь16 июня в 24 мая.

Если вы не хотите, чтобы это произошло, вам нужно где-то запомнить базовый год и основывать на нем свою арифметику.

Например, если "новый«понедельник - это 4 дня назад (потому что прошло 3 года), вы можете предпочесть выбрать понедельник на 3 дня раньше времени, чтобы не вычитать бесконечно дни, годы за годами.

Надеюсь, это поможет.

0 голосов
/ 19 января 2011

Ответ оказался довольно простым. Это оказалось методом проб и ошибок. Вот ответ.

, если год является високосным, вычтите 365 дней.

если год не високосный, вычтите 364 дня.

...