2011-01-18 14 views
5

Próbuję zrobić coś, co dla mnie jest nieco trudne. Ale jestem pewien, że ktoś ma pewien wgląd.NSDate - rok temu, dylemat

Biorąc pod uwagę datę, powiedzmy January 17, 2011, próbuję ustalić dzień, który odpowiada tej dacie rok temu. Tak więc January 17, 2011 jest poniedziałkiem, a rok temu ten dzień padł na January 18, 2010 (również w poniedziałek). Okazuje się, że January 18, 2010 jest 354 dni przed January 17, 2011. Początkowo sądziłem, że po prostu odejmuję 365 dni w roku wolnym od skoku i 366 dni w roku przestępnym, ale jeśli zrobisz to w tym przypadku, dostaniesz January 17, 2010, czyli niedzielę, a nie poniedziałek.

Więc w Objective-C z NSDate i NSCalendar, jak mogłaby wdrożyć funkcji, takich jak:

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

Innymi słowy, n-tej „powszedni” n-tego miesiąca (gdzie „dzień tygodnia” jest Poniedziałek, wtorek, środa itp.)

+3

będziesz musiał zdefiniować lepiej dokładnie jakie są Twoje oczekiwania; rok od 17 stycznia 2011 r. to 17 stycznia 2010 r. Czy chcesz (na przykład) n-tego poniedziałku n-tego miesiąca? –

+0

tak, n-ty "dzień powszedni" n-tego miesiąca. – CodeGuy

+0

Ten miesiąc ma pięć poniedziałków, a styczeń 2010 tylko cztery. Jaka jest data jednego roku przed 31 stycznia 2011 r. W tym schemacie daty? – Chuck

Odpowiedz

-8

Odpowiedź okazała się dość prosta. Okazało się, że z prób i błędów. Oto odpowiedź.

jeśli rok jest rokiem przestępnym, odejmij 365 dni.

jeśli rok nie jest rokiem przestępnym, odejmij 364 dni.

+0

następnie zaakceptuj własną odpowiedź. –

+3

Co może się nie udać? – titaniumdecoy

+0

To nawet nie robi tego, o co prosiłeś. To pytanie i jego odpowiedź to wrak pociągu. –

3

Nie mogę zagwarantować, że jest to najbardziej efektywny sposób, ale można to zrobić, używając NSCalendar i NSDateComponents. Przekaż instancję NSDate do [yourCalendar components:yourComponents fromDate:yourDate], odejmij rok od komponentów, a następnie użyj [yourCalendar dateFromComponents:yourComp].

Przepraszamy za niedostarczenie pełnego kodu, ale minęło trochę czasu odkąd pracowałem z tymi metodami i nie chcę podawać kodu, który nie zadziała.

+0

to również powoduje problem, o którym mówiłem w pytaniu. Jeśli "od" to 17 stycznia 2011 r., Ten pomysł powróci 17 stycznia 2010 r. (Jednak muszę go zwrócić 18 stycznia 2010 r.). – CodeGuy

22

użyć NSDateComponents tak:

- (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

to powoduje problem, o którym mówiłem w pytaniu. Jeśli "od" jest 17 stycznia 2011 r., To ta metoda powróci 17 stycznia 2010 r. (Jednak potrzebuję jej powrotu 18 stycznia 2010 r.). – CodeGuy

0

Substract 1 rok. Następnie odbierz 1 dzień, aż skończysz w tym samym dniu tygodnia, który chcesz.

Każdego roku "dni tygodnia" wracają o 1 dzień, z wyjątkiem przypadków, gdy między nimi jest 29, cofają się o 2 dni.

To dlatego, że rok to 52 tygodnie + 1 dzień (+2 lata przestępne).

Więc jeśli zastosujesz tę logikę w nieskończoność, skończysz, lata po latach, mając 16 czerwca na 24 maja.

Jeśli nie chcesz, aby tak się stało, musisz gdzieś zapamiętać rok referencyjny i oprzeć na nim swoją arytmetykę.

Na przykład, jeśli "nowy" poniedziałek ma 4 dni wstecz (ponieważ minęły 3 lata), możesz wybrać wybór na poniedziałek na 3 dni przed czasem, aby nie odejmować w nieskończoność dni, lat po latach.

Mam nadzieję, że to pomaga.

11

Jest to opisane w części Date and Time Programming Guide na Calendrical obliczeń Adding Components to a Date

szczególności, sposób zainteresowania jest dateByAddingComponents:toDate:options.

Na przykładzie firmy Apple jako podstawa, aby odjąć jeden rok od daty bieżącej, należy wykonać następujące czynności:

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];