NSDate - год назад, дилемма
-
12-10-2019 - |
Вопрос
Я пытаюсь сделать то, что для меня немного сложно.Но я уверен, что у кого-то есть понимание.
Учитывая дату, скажем 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 дня вперед по времени, чтобы не бесконечно вычитать дни, годы за годами.
Надеюсь, поможет.