Uzyskaj wartość całkowitą bieżącego roku w Javie

300

Muszę określić bieżący rok w Javie jako liczbę całkowitą. Mógłbym po prostu użyć java.util.Date(), ale jest przestarzały.

karlgrz
źródło
3
Nie, niejava.util.Date jest przestarzałe, nie od wersji Java 8. Niektóre z jego metod są przestarzałe, ale nie cała klasa. Ale należy unikać zarówno i jak są one notorycznie uciążliwe, mylące i błędne. Zamiast tego użyj albo java.time (w Javie 8) lub Joda-Time . java.util.Datejava.util.Calendar
Basil Bourque

Odpowiedzi:

636
int year = Calendar.getInstance().get(Calendar.YEAR);

Nie masz pewności, czy spełnia to kryteria nie konfigurowania nowego kalendarza? (Dlaczego sprzeciw wobec tego?)

Cagcowboy
źródło
1
Po zobaczeniu Twojej odpowiedzi kalendarz byłby dobrym obiektem do użycia. Szukałem jednej linijki i nie sądziłem, że Kalendarz miałby to dla mnie. Udowodniono, że jestem zły! Dzięki!
karlgrz
Co z współbieżnością, co jeśli inny wątek / fragment kodu biblioteki zmieni aktualny czas? Czy nie byłoby rozsądnie zmodyfikować go na coś takiego: Kalendarz c = Calendar.getInstance (); synchronized (c) {c.setTimeInMillis (System.currentTimeMillis ()); return c.get (Calendar.YEAR);}
jnr
1
Zwraca to inną wartość w różnych wersjach Androida. Porównuję Androida v4.1.2 z v4.2.1.
toobsco42
2
@ycnix Nie ma problemu z współbieżnością z kodem, więc nie ma potrzeby zwiększania jego kompilacji. Calendar.getInstance().get(Calendar.YEAR) jest atomowy w odniesieniu do zegara zmienianego zewnętrznie, a wykonywanie synchronized(c)nowej instancji zmiennej lokalnej byłoby tutaj w ogóle bardzo bezcelowe.
nos
5
import java.util.Calendar
Dominykas Mostauskis
139

Korzystanie Java 8 czas API (zakładając, że jesteś szczęśliwy, aby uzyskać dany rok domyślną strefę czasową Twojego systemu), można skorzystać z Year::nowmetody :

int year = Year.now().getValue();
assylias
źródło
7
Sugeruję, aby zawsze przekazywać opcjonalny ZoneIdargument nowzamiast polegać domyślnie na bieżącej domyślnej strefie JVM (która może się zmienić w dowolnym momencie podczas działania!).
Basil Bourque,
Który wygląda lubi to BTW: int year = Year.now(ZoneId.of("America/New_York")).getValue(); docs.oracle.com/javase/8/docs/api/java/time/Year.html#now--
bcmoney
25

Najprościej (przepraszamy za pomocą Kalendarza) jest:

 int year = Calendar.getInstance().get(Calendar.YEAR);

Jest też nowa data i godzina API JSR , jak Joda czas

zestaw narzędzi
źródło
Zwraca to inną wartość w różnych wersjach Androida. Porównuję Androida v4.1.2 z v4.2.1.
toobsco42
1
@ toobsco42 - spróbuj googling na „android calendar.year bug”
zestaw narzędzi
Hej @toolkit, robiłem badania bez powodzenia. Miałem nadzieję na bardziej szczegółową odpowiedź.
toobsco42
Usunąłem kartę SIM z telefonu w wersji 4.1.2. Dlatego sieć nie mogła zaktualizować daty i godziny w telefonie. W rezultacie telefon utknął w 2012 roku. Wygląda na to, że nie jest to błąd w 4.1.2.
toobsco42
14

Najłatwiej jest uzyskać rok z kalendarza.

// year is stored as a static member
int year = Calendar.getInstance().get(Calendar.YEAR);
conmulligan
źródło
Kalendarz. ROK nie jest bieżącym rokiem.
zestaw narzędzi
Calendar.YEAR jest zdefiniowany w ten sposób ... public final static int YEAR = 1;
cagcowboy
2
Funkcja API get () w kalendarzu pobiera dane znajdujące się w polu określonym przez stałą. Rok znajduje się w polu 1 w obiekcie kalendarza! Calendar.getInstance () pobiera bieżącą datę. java.sun.com/j2se/1.4.2/docs/api/java/util/…
Bob King
Zwraca to inną wartość w różnych wersjach Androida. Porównuję Androida v4.1.2 z v4.2.1.
toobsco42
Usunąłem kartę SIM z telefonu w wersji 4.1.2. Dlatego sieć nie mogła zaktualizować daty i godziny w telefonie. W rezultacie telefon utknął w 2012 roku. Wygląda na to, że nie jest to błąd w 4.1.2.
toobsco42
13

Możesz także użyć 2 metod z java.time.YearMonth(od Java 8):

import java.time.YearMonth;
...
int year = YearMonth.now().getYear();
int month = YearMonth.now().getMonthValue();
Zhurov Konstantin
źródło
Niepoprawnie powielasz inną odpowiedź opublikowaną dawno temu. I produkujecie miesiąc, który nie ma znaczenia dla pytania. I ignorujesz kluczową kwestię strefy czasowej. A twoje formatowanie jest nieuporządkowane. Cieszę się, że uczestniczysz w przepełnieniu stosu. Ale ta odpowiedź nie jest wystarczająco dobra. Edytuj, aby poprawić jego słabości i dodać więcej wartości niż ta, która została już zapewniona przez inne Odpowiedzi. Lub usuń swoją odpowiedź, zanim zbierze głosy negatywne. Ikona PS Super awatara!
Basil Bourque
Dzięki wielkie. Edytowałem. link różni się nieco od mojego
Zhurov Konstantin
10

Jeśli chcesz rok dowolnego obiektu daty, użyłem następującej metody:

public static int getYearFromDate(Date date) {
    int result = -1;
    if (date != null) {
        Calendar cal = Calendar.getInstance();
        cal.setTime(date);
        result = cal.get(Calendar.YEAR);
    }
    return result;
}
basZero
źródło
wynik to 1970!
Dr aNdRO,
10

tl; dr

ZonedDateTime.now(  ZoneId.of( "Africa/Casablanca" )  )
             .getYear()

Strefa czasowa

Odpowiedź przez Raffi Khatchadourian mądrze pokazuje, jak korzystać z nowego pakietu java.time w Javie 8. Ale odpowiedź nie odnosi się do kwestii krytycznej strefy czasowej w celu ustalenia terminu.

int year = LocalDate.now (). getYear ();

Ten kod zależy od bieżącej domyślnej strefy czasowej JVM. Strefa domyślna służy do określania aktualnej daty. Pamiętajcie na przykład, że w chwilę po północy w Paryżu data w Montrealu wciąż jest „wczoraj”.

Dlatego wyniki mogą się różnić w zależności od komputera, na którym działa, użytkownik / administrator zmieniający strefę czasową systemu operacyjnego hosta lub dowolny kod Java w dowolnym momencie zmieniający bieżącą wartość domyślną maszyny JVM. Lepiej określić strefę czasową.

Nawiasem mówiąc, zawsze używać nazw strefy czasowej , jak określone przez IANA . Nigdy nie używaj 3-4 literowych kodów, które nie są ani ustandaryzowane, ani unikalne.

java.time

Przykład w java.time Java 8.

int year = ZonedDateTime.now(  ZoneId.of( "Africa/Casablanca" )  ).getYear() ;

Joda-Time

Jakiś pomysł jak wyżej, ale przy użyciu biblioteki Joda-Time 2.7.

int year = DateTime.now( DateTimeZone.forID( "Africa/Casablanca" ) ).getYear() ;

Rok inkrementacji / dekrementacji

Jeśli Twoim celem jest przeskakiwanie o jeden rok naraz, nie musisz wyciągać numeru roku. Zarówno Joda-Time, jak i java.time mają metody dodawania / odejmowania rocznie. Te metody są inteligentne, radzą sobie z czasem letnim i innymi anomaliami.

Przykład w Joda-Time 2.7.

DateTime oneYearAgo = DateTime.now( DateTimeZone.forID( "Africa/Casablanca" ) ).minusYears( 1 ) ;
Basil Bourque
źródło
2
Wszystkie identyfikatory stref dla leniwych (jak ja): mkyong.com/java8/java-display-all-zoneid-and-its-utc-offset
FBB
1
@FBB Proponuję stronę Wikipedii, aby uzyskać oficjalną listę nazw stref czasowych IANA . Uwaga: strefy te zmieniają się zaskakująco często. Jeśli naprawdę chcesz informacji up-to-date, pobierz nową kopię w tzdatapliku danych samodzielnie. Możesz przejrzeć plik. I możesz zastąpić przestarzałe tzdata w swojej implementacji Java. Oracle zapewnia narzędzie aktualizujące dla JVM.
Basil Bourque,
4

Jeśli twoja aplikacja intensywnie wykorzystuje obiekty Date i Calendar, naprawdę powinieneś użyć Joda Time, ponieważ java.util.Datejest zmienna. java.util.Calendarma problemy z wydajnością, gdy jego pola są aktualizowane, i jest nieporadny w przypadku arytmetyki czasu i daty.

Alan
źródło
3

Możesz także użyć Java 8 LocalDate:

import java.time.LocalDate;
//...
int year = LocalDate.now().getYear();
Raffi Khatchadourian
źródło
@ AndrewT., Zdobądź ThreeTen Backport i będzie działał również w Javie 6 i 7.
Ole VV
3

Jak niektórzy ludzie odpowiedzieli powyżej:

Jeśli chcesz później użyć tej zmiennej, lepiej użyj:

int year;

year = Calendar.getInstance().get(Calendar.YEAR);

Jeśli potrzebujesz roku tylko na stan, lepiej użyj:

Calendar.getInstance().get(Calendar.YEAR)

Na przykład użycie go w czasie, gdy kontrole wprowadzone rok jest nie mniejszy niż bieżący rok 200 lub więcej niż bieżący rok (może być rokiem urodzenia):

import java.util.Calendar;
import java.util.Scanner;

public static void main (String[] args){

    Scanner scannernumber = new Scanner(System.in);
    int year;

    /*Checks that the year is not higher than the current year, and not less than the current year - 200 years.*/

    do{
        System.out.print("Year (Between "+((Calendar.getInstance().get(Calendar.YEAR))-200)+" and "+Calendar.getInstance().get(Calendar.YEAR)+") : ");
        year = scannernumber.nextInt();
    }while(year < ((Calendar.getInstance().get(Calendar.YEAR))-200) || year > Calendar.getInstance().get(Calendar.YEAR));
}
maral04
źródło
3

Użyj następującego kodu dla java 8:

LocalDate localDate = LocalDate.now();
int year = localDate.getYear();
int month = localDate.getMonthValue();
int date = localDate.getDayOfMonth();
KayV
źródło
0

W moim przypadku żadne z powyższych nie działa. Po wypróbowaniu wielu rozwiązań znalazłem poniżej jednego i zadziałało to dla mnie

import java.util.Scanner;
import java.util.Date;

public class Practice
{   
    public static void main(String[] args)
    {
        Date d=new Date();  
        int year=d.getYear();
        int currentYear=year+1900;    

        System.out.println(currentYear);

    }

}
Mayur Satav
źródło
Ta metoda jest przestarzała. Ta straszna klasa została wyparta wiele lat temu przez klasy java.time zdefiniowane w JSR 310. Zobacz nowoczesne rozwiązanie w odpowiedzi Assylias .
Basil Bourque,
-1

W wersji Java 8+ można (zaleca się) korzystać z biblioteki java.time . ISO 8601 określa standardowy sposób zapisywania dat: YYYY-MM-DDi java.time.Instantużywa go, więc (dla UTC):

import java.time.Instant;
int myYear = Integer.parseInt(Instant.now().toString().substring(0,4));

PS na wszelki wypadek (i skrócony do uzyskiwania String, nie int), używanie Calendarwygląda lepiej i można go rozpoznać w strefie.

Aleksiej Martianow
źródło
Ignorujesz kluczową kwestię strefy czasowej. Zobacz prostsze rozwiązanie w innej odpowiedzi .
Basil Bourque
-2

Możesz zrobić wszystko, używając matematyki Integer, bez konieczności tworzenia kalendarza:

return (System.currentTimeMillis()/1000/3600/24/365.25 +1970);

Mogę odpocząć przez godzinę lub dwie w nowym roku, ale nie mam wrażenia, że ​​to problem?

Ewan Makepeace
źródło
9
pracujesz dla jabłka? macworld.com/article/2023580/…
Stefan Paul Noack
wow, to jest bardzo ciężkie, sugerowałbym, aby było to proste, jak pokazał to cagcowboy.
LStrike,
To może nie być najlepsze we wszystkich okolicznościach, ale nie zasługuje na negatywne opinie.
JohnnyLambada
-4

Korzystam ze specjalnych funkcji w mojej bibliotece do pracy z int / dniami / miesiącami / rokami -

int[] int_dmy( long timestamp ) // remember month is [0..11] !!!
{
  Calendar cal = new GregorianCalendar(); cal.setTimeInMillis( timestamp );
  return new int[] { 
    cal.get( Calendar.DATE ), cal.get( Calendar.MONTH ), cal.get( Calendar.YEAR )
  };
};


int[] int_dmy( Date d ) { 
 ...
}
maks
źródło