Jak mogę uzyskać rok / miesiąc / dzień NSDate
obiektu, bez innych informacji? Zdaję sobie sprawę, że prawdopodobnie mógłbym to zrobić z czymś podobnym do tego:
NSCalendar *cal = [[NSCalendar alloc] init];
NSDateComponents *components = [cal components:0 fromDate:date];
int year = [components year];
int month = [components month];
int day = [components day];
Ale wydaje się, że jest to bardzo kłopotliwe dla czegoś tak prostego, jak uzyskanie NSDate
roku / miesiąca / dnia. Czy jest jakieś inne rozwiązanie?
objective-c
nsdate
nsdatecomponents
nscalendar
Richard J. Ross III
źródło
źródło
Odpowiedzi:
Ponieważ jest to najwyraźniej moja najpopularniejsza odpowiedź, spróbuję ją edytować, aby zawierała nieco więcej informacji.
Pomimo swojej nazwy,
NSDate
sama w sobie oznacza po prostu punkt w czasie maszyny, a nie datę. Nie ma korelacji między punktem w czasie określonym przezNSDate
a rok, miesiąc lub dzień. W tym celu musisz odwołać się do kalendarza. Dowolny moment zwróci informacje o różnych datach w oparciu o kalendarz, na który patrzysz (daty nie są takie same, na przykład w kalendarzu gregoriańskim i żydowskim), a kalendarz gregoriański jest najczęściej używanym kalendarzem w świat - zakładam - jesteśmy trochę stronniczy, żeNSDate
zawsze powinniśmy go używać.NSDate
, na szczęście jest o wiele bardziej dwustronny.Jak
NSCalendar
wspomniałeś, uzyskanie daty i godziny będzie musiało upłynąć , ale jest na to prostszy sposób:To generuje
NSDateComponents
obiekt zawierający dzień, miesiąc i rok z bieżącego kalendarza systemowego dla bieżącego dnia. ( Uwaga: niekoniecznie jest to bieżący kalendarz określony przez użytkownika , tylko domyślny kalendarz systemowy).Oczywiście, jeśli używasz innego kalendarza lub daty, możesz to łatwo zmienić. Lista dostępnych kalendarzy i jednostek kalendarza znajduje się w
NSCalendar
Odniesieniu do klasy . Więcej informacji na tematNSDateComponents
można znaleźć wNSDateComponents
Odwołaniu do klasy .Dla porównania, dostęp do poszczególnych komponentów z
NSDateComponents
jest raczej łatwy:Musisz tylko uważać:
NSDateComponents
nie będzie zawierał prawidłowych informacji dla pól, o które prosisz, chyba że wygenerowałeś je z tymi prawidłowymi informacjami (tj. ProśbąNSCalendar
o przekazanie tych informacjiNSCalendarUnit
).NSDateComponents
same w sobie nie zawierają żadnych informacji referencyjnych - są to po prostu proste struktury, które przechowują liczby, do których masz dostęp. Jeśli chcesz również uzyskać erę, na przykład, zNSDateComponents
, będziesz musiał karmić metodę z generatoraNSCalendar
zNSCalendarUnitEra
flagą.źródło
NSCalendar
„s+currentCalendar
metoda zwróci kalendarz systemowy, a więc jeśli telefon użytkownika jest ustawiona na tryb japoński lub tajski czasu, dostaniesz inny rok. Jeśli chcesz wymusić określony system kalendarza, utwórz kalendarz i zainicjuj go przy użyciu odpowiednich ustawień regionalnych. Na przykład, aby wymusić kalendarz gregoriański, należy użyć następujących opcji:[[NSCalendar alloc] initWithCalendarIdentifier:NSGregorianCalendar]
Możesz uzyskać oddzielny składnik NSDate za pomocą NSDateFormatter:
Jeśli chcesz uzyskać numer miesiąca zamiast skrótu, użyj „MM”. Jeśli chcesz uzyskać liczby całkowite, użyj
[myDayString intValue];
źródło
Aby przeredagować doskonały (i działający!) Kod Itai, oto jak wyglądałaby przykładowa klasa pomocnicza, aby zwrócić wartość roku danej zmiennej NSDate.
Jak widać, wystarczy zmodyfikować ten kod, aby uzyskać miesiąc lub dzień.
(Nie mogę uwierzyć, że musimy napisać własne podstawowe funkcje daty iOS w 2013 roku ...)
Jeszcze jedno: nigdy nie używaj <i> do porównywania dwóch wartości NSDate.
XCode chętnie zaakceptuje taki kod (bez żadnych błędów i ostrzeżeń), ale jego wyniki są loterią. Państwo musi użyć funkcji „Porównaj” aby porównać NSDates:
źródło
W Swift 2.0:
źródło
Piszę tę odpowiedź, ponieważ jest to jedyne podejście, które nie zwraca opcji przed
NSDateComponent
zmiennymi i / lub wymusza ich rozpakowywanie (także w Swift 3).Szybki 3
Swift 2
Dodatkowa zabawna wersja Swift 3
źródło
Nowości w iOS 8
ObjC
Szybki
źródło
Jeśli celujesz w iOS 8+, możesz skorzystać z nowych
NSCalendar
metod wygody, aby osiągnąć ten cel w bardziej zwięzłym formacie.Najpierw utwórz
NSCalendar
i użyj tego, coNSDate
jest wymagane.Możesz wyodrębnić komponenty indywidualnie poprzez
component:fromDate:
Lub, bardziej zwięźle, użyj
NSInteger
wskaźników za pośrednictwemgetEra:year:month:day:fromDate:
Aby uzyskać więcej informacji i przykładów, zapoznaj się z NSDate Manipulation Made Easy w iOS 8 . Uwaga, napisałem post.
źródło
Począwszy od systemu iOS 8.0 (i OS X 10), można użyć metody komponentu , aby uprościć uzyskanie komponentu z jedną datą:
Powinno to uprościć i mam nadzieję, że zostanie to skutecznie wdrożone.
źródło
Jeśli chcesz uzyskać poszczególne NSDateComponents z NSDate, zdecydowanie potrzebujesz rozwiązania sugerowanego przez Itai Ferber. Ale jeśli chcesz przejść z NSDate bezpośrednio do NSString, możesz użyć NSDateFormatter .
źródło
źródło
Oto rozwiązanie w Swift:
źródło
Spróbuj tego . . .
Fragment kodu:
Podaje bieżący rok, miesiąc, datę
źródło
Spróbuj wykonać następujące czynności:
źródło
Swift 2.x
Możesz użyć go jako
Wynik
źródło
Szybki
Łatwiejszy sposób na uzyskanie dowolnych elementów daty jako opcjonalnego ciągu.
źródło
robię w ten sposób ....
źródło
Aby uzyskać ciąg czytelny dla człowieka (dzień, miesiąc, rok), możesz:
źródło