2011-01-18 5 views
5

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

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

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

+3

Вы собираетесь иметь, чтобы лучше определить точно, что ваши ожидания; один год назад с 17 января 2011 года - 17 января 2010 года. Вы хотите (например) в nth Monday of nth month? –

+0

Да, n-й «будний день» n-го месяца. – CodeGuy

+0

В этом месяце пять понедельников, а в январе 2010 года было всего четыре. Какая дата за год до 31 января 2011 года в этой схеме? – Chuck

ответ

-8

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

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

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

+0

, тогда примите ваш собственный ответ. –

+3

Что может пойти не так? – titaniumdecoy

+0

Это даже не делает то, что вы просили. Этот вопрос и его ответ - поездка. –

3

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

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

+0

это также приводит к проблеме, которую я изложил в вопросе. Если «от» - 17 января 2011 года, то эта идея вернется 17 января 2010 года (однако мне нужно, чтобы она вернулась 18 января 2010 года). – CodeGuy

22

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

} 
+0

Это приводит к проблеме, которую я изложил в вопросе. Если «от» - 17 января 2011 года, то этот метод вернется 17 января 2010 года (однако мне нужно, чтобы он вернулся 18 января 2010 года). – CodeGuy

0

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

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

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

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

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

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

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

11

Это описано в разделе, посвященном Календарные вычисления Date and Time Programming Guide, Adding Components to a Date

В частности, способ представляет интерес 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]; 
Смежные вопросы