Вопрос

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

Учитывая дату, скажем 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

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

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

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

Другие советы

Вы используете 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];

}

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

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

Используя пример 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];

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

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

Вычтите 1 год.Затем вычтите 1 день, пока не получите тот день недели, который вы хотите.

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

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

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

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

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

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

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top