Chcę zwrócić wiek w latach jako int w metodzie Java. To, co mam teraz, jest następujące, w którym getBirthDate () zwraca obiekt Date (z datą urodzenia ;-)):
public int getAge() {
long ageInMillis = new Date().getTime() - getBirthDate().getTime();
Date age = new Date(ageInMillis);
return age.getYear();
}
Ale ponieważ getYear () jest przestarzałe, zastanawiam się, czy istnieje lepszy sposób na zrobienie tego? Nie jestem nawet pewien, czy to działa poprawnie, ponieważ nie mam (jeszcze) testów jednostkowych.
Odpowiedzi:
JDK 8 sprawia, że jest to łatwe i eleganckie:
Test JUnit w celu wykazania jego zastosowania:
Wszyscy powinni już używać JDK 8. Wszystkie wcześniejsze wersje już minęły.
źródło
null
s, ale zamiast tego użyćObjects.requireNonNull
.Sprawdź Joda , który upraszcza obliczenia daty / czasu (Joda jest również podstawą nowego standardowego interfejsu API daty / czasu w Javie, więc nauczysz się wkrótce standardowego API).
EDYCJA: Java 8 ma coś bardzo podobnego i warto to sprawdzić.
na przykład
co jest tak proste, jak tylko chcesz. Rzeczy sprzed wersji Java 8 są (jak zidentyfikowałeś) nieco nieintuicyjne.
źródło
źródło
Nowoczesna odpowiedź i przegląd
a) Java-8 (pakiet java.time)
Zwróć uwagę, że wyrażenie
LocalDate.now()
jest niejawnie powiązane ze strefą czasową systemu (która jest często pomijana przez użytkowników). Dla jasności ogólnie lepiej jest użyć przeciążonej metody,now(ZoneId.of("Europe/Paris"))
podając wyraźną strefę czasową (tutaj jako przykład „Europa / Paryż”). Jeśli żądana jest strefa czasowa systemu, to ja wolę pisaćLocalDate.now(ZoneId.systemDefault())
aby powiązanie ze strefą czasową systemu było jaśniejsze. To wymaga większego wysiłku przy pisaniu, ale ułatwia czytanie.b) Czas Joda
Należy pamiętać, że zaproponowane i zaakceptowane rozwiązanie Joda-Time daje inny wynik obliczeń dla dat pokazanych powyżej (rzadki przypadek), a mianowicie:
Uważam to za mały błąd, ale zespół Jody ma inny pogląd na to dziwne zachowanie i nie chce go naprawiać (dziwne, ponieważ data zakończenia miesiąca jest mniejsza niż data rozpoczęcia, więc rok powinien być jeden mniej). Zobacz także to zamknięte wydanie .
c) java.util.Calendar itp.
Dla porównania zobacz różne inne odpowiedzi. W ogóle nie polecałbym używania tych przestarzałych klas, ponieważ wynikowy kod jest nadal podatny na błędy w niektórych egzotycznych przypadkach i / lub zbyt skomplikowany, biorąc pod uwagę fakt, że pierwotne pytanie brzmi tak prosto. W 2015 roku mamy naprawdę lepsze biblioteki.
d) o Date4J:
Proponowane rozwiązanie jest proste, ale czasami zawiedzie w przypadku lat przestępnych. Samo oszacowanie dnia roku nie jest wiarygodne.
e) Moja własna biblioteka Time4J :
Działa to podobnie do rozwiązania Java-8. Po prostu wymień
LocalDate
naPlainDate
iChronoUnit.YEARS
doCalendarUnit.YEARS
. Jednak uzyskanie informacji „dzisiaj” wymaga wyraźnego odniesienia do strefy czasowej.źródło
LocalDate.now
. W przypadku pominięcia bieżąca domyślna strefa czasowa maszyny JVM jest niejawnie stosowana. Ta wartość domyślna może zmieniać się między maszynami / systemami operacyjnymi / ustawieniami, a także może w dowolnym momencie podczas wykonywania przez wywołanie dowolnego kodusetDefault
. Zalecam być konkretnym, na przykładLocalDate.now( ZoneId.for( "America/Montreal" ) )
źródło
(birthDate.get(Calendar.DAY_OF_YEAR) - today.get(Calendar.DAY_OF_YEAR) > 3)
? Istnienie porównań miesiąca i dnia miesiąca wydaje się bezcelowe.Po prostu używam stałej wartości milisekund w roku na swoją korzyść:
źródło
Jeśli używasz GWT, będziesz ograniczony do korzystania z java.util.Date, oto metoda, która przyjmuje datę jako liczby całkowite, ale nadal używa java.util.Date:
źródło
Prawidłowa odpowiedź przy użyciu JodaTime to:
Jeśli chcesz, możesz nawet skrócić go do jednej linii. Skopiowałem pomysł z odpowiedzi BrianAgnew , ale uważam, że jest to bardziej poprawne, jak widać z tamtejszych komentarzy (i dokładnie odpowiada na pytanie).
źródło
Z biblioteką date4j :
źródło
To jest ulepszona wersja powyższego ... biorąc pod uwagę, że chcesz, aby wiek był „int”. ponieważ czasami nie chcesz zapełniać swojego programu wieloma bibliotekami.
źródło
Być może zaskakujące jest to, że nie musisz wiedzieć, ile dni lub miesięcy przypada na rok ani ile dni przypada na te miesiące, podobnie nie musisz wiedzieć o latach przestępnych, sekundach przestępnych ani innych tych rzeczy za pomocą tej prostej, w 100% dokładnej metody:
źródło
Spróbuj skopiować ten kod do swojego kodu, a następnie użyj metody, aby uzyskać wiek.
źródło
Używam tego fragmentu kodu do obliczania wieku, mam nadzieję, że to pomaga ... brak bibliotek
źródło
Pola urodzenia i skutku to pola daty:
Jest to w zasadzie modyfikacja rozwiązania Johna O bez użycia zdekapitalizowanych metod. Spędziłem sporo czasu próbując zmusić jego kod do pracy w moim kodzie. Może to uratuje tym razem innych.
źródło
A co z tym?
źródło
String
dateofbirth
ma datę urodzenia. a format jest dowolny (zdefiniowany w następującym wierszu):Oto jak sformatować:
Zmienna
ageStr
będzie miała lata.źródło
Elegancki, pozornie poprawny wariant rozwiązania Yarona Ronena oparty na różnicy znaczników czasu.
Ja w tym testów jednostkowych do udowodnienia, kiedy i dlaczego to nie jest poprawne . Jest to niemożliwe z powodu (prawdopodobnie) różnej liczby dni przestępnych (i sekund) w jakiejkolwiek różnicy w sygnaturze czasowej. Rozbieżność powinna wynosić max + -1 dzień (i jedną sekundę) dla tego algorytmu, patrz test2 (), podczas gdy rozwiązanie Yarona Ronena oparte na całkowicie stałym założeniu
timeDiff / MILLI_SECONDS_YEAR
może różnić się o 10 dni dla 40-latka, ale ten wariant jest również niepoprawny.Jest to trudne, ponieważ ten ulepszony wariant, wykorzystujący formułę
diffAsCalendar.get(Calendar.YEAR) - 1970
, zwraca prawidłowe wyniki przez większość czasu, ponieważ liczba lat przestępnych średnio jest taka sama między dwiema datami.źródło
źródło
źródło
Oto kod java do obliczania wieku w roku, miesiącu i dniach.
źródło
Najłatwiejszy sposób bez żadnych bibliotek:
źródło
ChronoUnit.YEARS.between( LocalDate.of( 1968 , Month.MARCH , 23 ) , LocalDate.now() )
. Zobacz poprawną odpowiedźDateUtils
jest bibliotekąW Javie 8 możemy obliczyć wiek osoby za pomocą jednej linii kodu:
źródło
źródło
źródło
źródło
źródło
źródło
Doceniam wszystkie poprawne odpowiedzi, ale to jest odpowiedź kotlin na to samo pytanie
Mam nadzieję, że byłby pomocny dla programistów kotlin
źródło