wake-up-neo.net

Warum gibt Java Date.getYear () 111 statt 2011 zurück?

Ich habe Probleme beim Parsen eines String-Datums in ein Date-Objekt. Ich verwende eine DateFormat, um die Zeichenfolge zu analysieren, und wenn ich den Wert des Datums drucke, wird mir angezeigt, was ich erwartet habe.

Aber wenn ich versuche, den Tag, den Monat oder das Jahr zu bekommen, werden mir falsche Werte angezeigt. Zum Beispiel ist das Jahr 2011, aber wenn ich .getYear() mache, bekomme ich 111. Ich habe keine Ahnung, warum das so ist. Hier ist das relevante Codesegment:

    Date dateFrom = null;

    String gDFString = g.getDateFrom();

    System.out.println(gDFString);

    DateFormat df = new SimpleDateFormat("dd/MM/yyyy");

    try {
        dateFrom = df.parse("04/12/2011");

        System.out.println(dateFrom);

        System.out.println(dateFrom.getYear());
    } catch (ParseException e) {
        e.printStackTrace();
    }

Wenn ich dateFrom drucke, erhalte ich Sun Dec 04 00:00:00 GMT 2011, was Sie erwarten würden. Beim Drucken von .getYear() wird jedoch 111 zurückgegeben.

Ich muss in der Lage sein, den Tag, den Monat und das Jahr des Datums für eine Zeitreihengrafik abzurufen.

41
Ben Calder

Diese Methoden wurden veraltet. Verwenden Sie stattdessen die Klasse Kalender


import Java.text.DateFormat;
import Java.text.ParseException;
import Java.text.SimpleDateFormat;
import Java.util.Calendar;

public final class DateParseDemo {
    public static void main(String[] args){
         final DateFormat df = new SimpleDateFormat("MM/dd/yyyy");
         final Calendar c = Calendar.getInstance();
         try {
             c.setTime(df.parse("04/12/2011"));
             System.out.println("Year = " + c.get(Calendar.YEAR));
             System.out.println("Month = " + (c.get(Calendar.MONTH)));
             System.out.println("Day = " + c.get(Calendar.DAY_OF_MONTH));
         } 
         catch (ParseException e) {
             e.printStackTrace();
         }
    }
}

Ausgabe:

Year = 2011
Month = 3
Day = 12

Das Feld month ist 0-basiert. Dies bedeutet, dass Januar = 0 und Dezember = 11. Wie von Javadoc angegeben, 

Feldnummer für get und set, die den Monat angibt. Das ist ein kalenderspezifischer Wert. Der erste Monat des Jahres in der Gregorianischen. und Julianische Kalender sind JANUARY, dh 0; das letzte hängt von der .__ ab. Anzahl der Monate in einem Jahr.

42
mre

Javadoc zur Rettung:

Veraltet Ab JDK Version 1.1 ersetzt durch Calendar.get (Calendar.YEAR) - 1900.

Gibt einen Wert zurück, der das Ergebnis der Subtraktion von 1900 von .__ ist. Jahr, das den von .__ dargestellten Zeitpunkt enthält oder mit dem Zeitpunkt beginnt. Dieses Date-Objekt, wie in der lokalen Zeitzone interpretiert.

Sie sollten keine veralteten Methoden verwenden. Veraltete Methoden sind Methoden, die nicht mehr verwendet werden sollten. Was auch immer die Methode ist, die Sie verwenden, lesen Sie den Javadoc, um zu erfahren, was sie tut.

10
JB Nizet

Präsident Evil hat es auf den Punkt gebracht, Date.getYear() liefert einen Wert zurück, der das Ergebnis der Subtraktion von 1900 von dem Jahr ist, das enthält. Und du solltest es nicht benutzen.

Die schnelle Lösung für den Code in der Frage lautet jedoch:

Date dateFrom = null;

String gDFString = g.getDateFrom();

System.out.println(gDFString);

DateFormat df = new SimpleDateFormat("dd/MM/yyyy");

try {
    dateFrom = df.parse("04/12/2011");

    System.out.println(dateFrom);

    // Add 1900 to dateFrom.getYear() 

    System.out.println(dateFrom.getYear()+1900);
} catch (ParseException e) {
    e.printStackTrace();
}
9
Dimitar Pavlov

tl; dr

int year = 
    LocalDate.parse( 
        "04/12/2011" , 
        DateTimeFormatter.ofLocalizedDate( FormatStyle.SHORT ).withLocale( Locale.US ) 
    ).getYear() ;  

2011

Java.time

Das lästige Java.util.Date class und seine Geschwister werden jetzt durch die hervorragenden Java.time-Klassen ersetzt.

String input = "04/12/2011";
Locale locale = Locale.US;
DateTimeFormatter f = DateTimeFormatter.ofLocalizedDate( FormatStyle.SHORT ).withLocale( locale );
LocalDate ld = LocalDate.parse( input , f );

Die Java.time-Klassen verwenden eine vernünftige Nummerierung mit:

  • Monate 1-12 für Januar-Dezember
  • 2011 bedeutet 2011
  • Wochentage sind 1-7 für Montag-Sonntag (per ISO 8601 ).

Fragen Sie das LocalDate nach seinen Bestandteilen ab.

int year = ld.getYear();  // 2011
int month = ld.getMonthValue();  // 4
int dayOfMonth = ld.getDayOfMonth();  // 12

Sie können sogar nach dem automatisch lokalisierten Monats- und Wochentagsnamen fragen.

String monthName = ld.getMonth().getDisplayName( TextStyle.FULL_STANDALONE , Locale.CANDA_FRENCH ); // avril

Über Java.time

Das Java.time Framework ist in Java 8 und höher. Diese Klassen ersetzen die lästigen alten Datum-Zeit-Klassen wie Java.util.Date, .Calendar, & Java.text.SimpleDateFormat.

Das Joda-Time -Projekt, das sich jetzt im Wartungsmodus befindet, rät zur Migration auf Java.time.

Weitere Informationen finden Sie im Oracle Tutorial . Durchsuchen Sie Stack Overflow nach vielen Beispielen und Erklärungen.

Ein Großteil der Java.time-Funktionalität wird auf Java 6 & 7 in ThreeTen-Backport zurückportiert und weiter angepasst an Android in - ThreeTenABP (siehe Verwendung… ).

Das ThreeTen-Extra Projekt erweitert Java.time um zusätzliche Klassen. Dieses Projekt ist ein Testfeld für mögliche zukünftige Ergänzungen von Java.time. Hier finden Sie möglicherweise einige nützliche Klassen wie Interval, YearWeek, YearQuarter und mehr.

4
Basil Bourque

Dies ist nur eine Vermutung, aber die 111 könnte die Anzahl der Jahre seit 1900 sein. Schauen Sie sich die Dokumentation an oder machen Sie ein paar Tests, um dies zu überprüfen (ich kann momentan nicht nachsehen)

3
epochengine

http://download.Oracle.com/javase/1.4.2/docs/api/Java/util/Date.html#getYear%28%29

Die Spezifikation besagt, dass das Jahr minus 1900 zurückgegeben wird. Wahrscheinlich eine gute Idee, um auch veraltete Methoden zu vermeiden.

3
bdares