Chcę pobrać rok, miesiąc, dzień itp. Z daty Java, aby porównać z datą kalendarza gregoriańskiego w Javie. czy to możliwe?

231

Mam obiekt Date w Javie przechowywany jako typ Data Java.

Mam również datę utworzenia kalendarza gregoriańskiego. Gregoriańska data kalendarzowa nie ma parametrów i dlatego jest instancją dzisiejszej daty (i godziny?).

Z datą java chcę uzyskać rok, miesiąc, dzień, godzinę, minutę i sekundy z typu daty java i porównać datę gregoriancalendar.

Widziałem, że w tej chwili data Java jest przechowywana jako długa i jedyne dostępne metody wydają się po prostu pisać jako sformatowany ciąg daty. Czy istnieje sposób na dostęp do roku, miesiąca, dnia itp.?

Widziałem, że getYear(), getMonth()itd metody Dateklasy są nieaktualne. Zastanawiałem się, jaka jest najlepsza praktyka korzystania z instancji Java Date, którą mam z tą GregorianCalendardatą.

Moim celem końcowym jest wykonanie obliczenia daty, dzięki czemu mogę sprawdzić, czy data Java jest w ciągu tylu godzin, minut itp. Od dzisiejszej daty i godziny.

Nadal jestem nowicjuszem w Javie i trochę mnie to zastanawia.

daveb
źródło
1
Hej, czego używasz, nie używaj Date.getYear(). Ma problemy (których nie wiem). Date.getYear()raz przeanalizowałem moją datę 30.06.2017 i zwróciłem rok jako 117. Zobacz, gdzie wylądował dwa tysiące lat temu. Ale kiedy drukuję po prostu obiekt daty, wynik był w porządku, ale nie Date.getYear();.
Seenivasan
FYI: Używasz kłopotliwych starych klas daty i czasu, które są teraz starsze, zastąpione nowoczesnymi klasami java.time.
Basil Bourque,

Odpowiedzi:

545

Użyj czegoś takiego:

Date date; // your date
// Choose time zone in which you want to interpret your Date
Calendar cal = Calendar.getInstance(TimeZone.getTimeZone("Europe/Paris"));
cal.setTime(date);
int year = cal.get(Calendar.YEAR);
int month = cal.get(Calendar.MONTH);
int day = cal.get(Calendar.DAY_OF_MONTH);
// etc.

Uwaga, miesiące zaczynają się od 0, a nie 1.

Edycja : Od wersji Java 8 lepiej jest używać java.time.LocalDate niż java.util.Calendar . Zobacz tę odpowiedź za, jak to zrobić.

Florent Guillaume
źródło
4
Możesz użyć cal.add(Calendar.DAY_OF_MONTH, -48)do wykonywania arytmetyki dziennej na obiektach kalendarza. I możesz porównać dwa obiekty kalendarza za pomocą cal.compareTo(anotherCal).
Florent Guillaume
1
Genialne, na zdrowie Florent! Czy powyższe oznacza, że ​​kalendarz zwróci zaktualizowany rok i dzień, sekundy, minuty i sekundy, gdy zostaną użyte metody pobierania kalendarza? Dave
daveb
11
Pamiętaj, że miesiąc zaczyna się od 0, a nie 1 (tj. Styczeń = 0). docs.oracle.com/javase/6/docs/api/java/util/Calendar.html#MONTH
Steve Kuo
10
Dlaczego JAVA jest tak niewygodna?
Kimchi Man,
3
Ponieważ data i kalendarz są stare i źle zaprojektowane. Java 8 ma znacznie lepsze obiekty danych / czasu, patrz oracle.com/technetwork/articles/java/…
Florent Guillaume
88

W Javie 8 i nowszych można konwertować obiekt Date na obiekt LocalDate, a następnie łatwo uzyskać rok, miesiąc i dzień.

Date date = new Date();
LocalDate localDate = date.toInstant().atZone(ZoneId.systemDefault()).toLocalDate();
int year  = localDate.getYear();
int month = localDate.getMonthValue();
int day   = localDate.getDayOfMonth();

Zauważ, że getMonthValue()zwraca wartość int od 1 do 12.

Ortomala Lokni
źródło
10
Teraz jest 2016, uważam, że używanie LocalDatew Javie 8 to najlepsze rozwiązanie, które oszczędza Twój czas, inne rozwiązanie używa Calendari Datejest pełne kłopotów.
AnnieFromTaiwan
2
Świetna odpowiedź - zdecydowanie najlepiej użyć java.time i unikać kłopotliwych starych zajęć z datą i godziną. Zwróć też uwagę, jak ta odpowiedź mądrze rozwiązuje problem strefy czasowej. W danym momencie data zmienia się na całym świecie w zależności od strefy czasowej.
Basil Bourque,
1
Niestety interfejs API w wersji 26+ dla Androida.
Wiktor Kalinowski,
14

Możesz zrobić coś takiego, to wyjaśni, jak Datedziała klasa.

String currentDateString = "02/27/2012 17:00:00";
SimpleDateFormat sd = new SimpleDateFormat("MM/dd/yyyy HH:mm:ss");
Date currentDate = sd.parse(currentDateString);

String yourDateString = "02/28/2012 15:00:00";
SimpleDateFormat yourDateFormat = new SimpleDateFormat("MM/dd/yyyy HH:mm:ss");

Date yourDate = yourDateFormat.parse(yourDateString);

if (yourDate.after(currentDate)) {
    System.out.println("After");
} else if(yourDate.equals(currentDate)) {
    System.out.println("Same");
} else {
    System.out.println("Before");
}
javaCity
źródło
Cześć JavaCity, Dzięki za to. to jest bardzo przydatne. W tej chwili staram się unikać parsowania łańcucha dat. Będę musiał to przeanalizować później, gdy jednak użytkownicy aplikacji będą ustawiać rok, dzień i miesiąc. Zamierzałem zbudować ciąg do analizy w SimpleDateFormat. Powyższe jest bardzo przydatne, aby zobaczyć to w akcji. Moja data Java została utworzona jako data i godzina od momentu jej utworzenia dzień temu. Teraz chcę porównać z datą gregoriancalendar, która została dziś utworzona. Serdeczne podziękowania
daveb
8
Popraw kod ... mała litera mmoznacza minuty, a wielka MMoznacza miesiąc roku.
YoYo
12
    Date date = new Date();

    SimpleDateFormat simpleDateFormat = new SimpleDateFormat("EEEE");

    System.out.println("DAY "+simpleDateFormat.format(date).toUpperCase());

    simpleDateFormat = new SimpleDateFormat("MMMM");
    System.out.println("MONTH "+simpleDateFormat.format(date).toUpperCase());

    simpleDateFormat = new SimpleDateFormat("YYYY");
    System.out.println("YEAR "+simpleDateFormat.format(date).toUpperCase());

EDYCJA: Dane wyjściowe dla date= Fri Jun 15 09:20:21 CEST 2018to:

DAY FRIDAY
MONTH JUNE
YEAR 2018
Az.MaYo
źródło
Jeśli wstawiłeś przynajmniej wynik, ludzie mogliby zdecydować, czy może to być dla nich przydatne, czy nie, bez konieczności uruchamiania kodu.
SantiBailors
6
private boolean isSameDay(Date date1, Date date2) {
    Calendar calendar1 = Calendar.getInstance();
    calendar1.setTime(date1);
    Calendar calendar2 = Calendar.getInstance();
    calendar2.setTime(date2);
    boolean sameYear = calendar1.get(Calendar.YEAR) == calendar2.get(Calendar.YEAR);
    boolean sameMonth = calendar1.get(Calendar.MONTH) == calendar2.get(Calendar.MONTH);
    boolean sameDay = calendar1.get(Calendar.DAY_OF_MONTH) == calendar2.get(Calendar.DAY_OF_MONTH);
    return (sameDay && sameMonth && sameYear);
}
evya
źródło
3
    Date queueDate = new SimpleDateFormat("yyyy-MM-dd").parse(inputDtStr);
    Calendar queueDateCal = Calendar.getInstance();
    queueDateCal.setTime(queueDate);
    if(queueDateCal.get(Calendar.DAY_OF_YEAR)==Calendar.getInstance().get(Calendar.DAY_OF_YEAR))
{
    "same day of the year!";
 }
rabi
źródło
1
Oczekuje się, że odpowiedzi na temat przepełnienia stosu będą zawierać dyskusje i wyjaśnienia, a nie tylko fragmenty kodu. W twoim kodzie zdecydowanie można by wyjaśnić.
Basil Bourque,
1
Do Twojej wiadomości, strasznie kłopotliwe stare klasy daty i czasu, takie jak java.util.Date, java.util.Calendari java.text.SimpleDateFormatsą teraz spuścizną , wyparte przez klasy java.time wbudowane w Javę 8 i nowsze wersje . Zobacz samouczek Oracle .
Basil Bourque
2
@Test
public void testDate() throws ParseException {
    long start = System.currentTimeMillis();
    long round = 100000l;
    for (int i = 0; i < round; i++) {
        StringUtil.getYearMonthDay(new Date());
    }
    long mid = System.currentTimeMillis();
    for (int i = 0; i < round; i++) {
        StringUtil.getYearMonthDay2(new Date());
    }
    long end = System.currentTimeMillis();
    System.out.println(mid - start);
    System.out.println(end - mid);
}

public static Date getYearMonthDay(Date date) throws ParseException {
    SimpleDateFormat f = new SimpleDateFormat("yyyyyMMdd");
    String dateStr = f.format(date);
    return f.parse(dateStr);
}

public static Date getYearMonthDay2(Date date) throws ParseException {
    Calendar c = Calendar.getInstance();
    c.setTime(date);
    c.set(Calendar.SECOND, 0);
    c.set(Calendar.MINUTE, 0);
    c.set(Calendar.HOUR_OF_DAY, 0);
    return c.getTime();
}
public static int compare(Date today, Date future, Date past) {
    Date today1 = StringUtil.getYearMonthDay2(today);
    Date future1 = StringUtil.getYearMonthDay2(future);
    Date past1 = StringUtil.getYearMonthDay2(past);
    return today.compare // or today.after or today.before
}

getYearMonthDay2 (rozwiązanie kalendarza) jest dziesięć razy szybsze. Teraz masz rrrr MM dd 00 00 00, a następnie porównaj używając date.compare

Tiina
źródło
2

To może być łatwiejsze

     Date date1 = new Date("31-May-2017");
OR
    java.sql.Date date1 = new java.sql.Date((new Date()).getTime());

    SimpleDateFormat formatNowDay = new SimpleDateFormat("dd");
    SimpleDateFormat formatNowMonth = new SimpleDateFormat("MM");
    SimpleDateFormat formatNowYear = new SimpleDateFormat("YYYY");

    String currentDay = formatNowDay.format(date1);
    String currentMonth = formatNowMonth.format(date1);
    String currentYear = formatNowYear.format(date1);
Abdur Rahman
źródło
-2

Ostrożnie montuj zacznij od 0, a nie 1. A także kalendarza używaj pm tak jak jestem, więc bądź bardzo ostrożny, gdy używasz godzin i minut.

Date your_date;
Calendar cal = Calendar.getInstance(); 
cal.setTime(your_date);
int year = cal.get(Calendar.YEAR);
int month = cal.get(Calendar.MINUTE);

harun ugur
źródło
1
Lepiej korzystać z nowoczesnego kodu java.time, który zastępuje te kłopotliwe, stare klasy pokazane tutaj. Zobacz poprawną odpowiedź
Basil Bourque,
Dziękuję za odpowiedź i sugestie. Jest bardzo lepiej.
harun ugur