Ben Calder
Ben Calder

Reputation: 457

Why does Java's Date.getYear() return 111 instead of 2011?

I am having a bit of trouble parsing a string date to a Date object. I use a DateFormat to parse the string, and when I print the value of the date, it gives me what I expect.

But when I try get the day, the month or the year it gives me the wrong values. For instance, the year is 2011, but when I do .getYear() it gives me 111. I have no idea why this is happening. Here is the relevant code segment:

    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();
    }

When I out print dateFrom, I get Sun Dec 04 00:00:00 GMT 2011, which is what you would expect. But printing .getYear() returns 111.

I need to be able to get the day, month and year of the date for a time series graph.

Upvotes: 44

Views: 54103

Answers (6)

Basil Bourque
Basil Bourque

Reputation: 338181

tl;dr

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

2011

java.time

The troublesome java.util.Date class and its siblings are now supplanted by the excellent java.time classes.

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

The java.time classes utilize sane numbering, with:

  • Months 1-12 for January-December
  • 2011 means 2011
  • Days of week are 1-7 for Monday-Sunday (per ISO 8601).

Interrogate the LocalDate for its constituent parts.

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

You can even ask for automatically localized name of month and name of day-of-week.

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

About java.time

The java.time framework is built into Java 8 and later. These classes supplant the troublesome old date-time classes such as java.util.Date, .Calendar, & java.text.SimpleDateFormat.

The Joda-Time project, now in maintenance mode, advises migration to java.time.

To learn more, see the Oracle Tutorial. And search Stack Overflow for many examples and explanations.

Much of the java.time functionality is back-ported to Java 6 & 7 in ThreeTen-Backport and further adapted to Android in ThreeTenABP (see How to use…).

The ThreeTen-Extra project extends java.time with additional classes. This project is a proving ground for possible future additions to java.time. You may find some useful classes here such as Interval, YearWeek, YearQuarter, and more.

Upvotes: 4

mre
mre

Reputation: 44240

Those methods have been deprecated. Instead, use the Calendar class.


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();
         }
    }
}

Output:

Year = 2011
Month = 3
Day = 12

And as for the month field, this is 0-based. This means that January = 0 and December = 11. As stated by the javadoc,

Field number for get and set indicating the month. This is a calendar-specific value. The first month of the year in the Gregorian and Julian calendars is JANUARY which is 0; the last depends on the number of months in a year.

Upvotes: 46

Dimitar Pavlov
Dimitar Pavlov

Reputation: 300

President Evil nailed it, Date.getYear() returns a value that is the result of subtracting 1900 from the year that contains. And you you shouldn't use it.

But quick fix for the code in the question is:

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();
}

Upvotes: 9

user684934
user684934

Reputation:

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

The specification states that it returns the year minus 1900. Probably a good idea to avoid deprecated methods as well.

Upvotes: 4

JB Nizet
JB Nizet

Reputation: 691635

Javadoc to the rescue:

Deprecated. As of JDK version 1.1, replaced by Calendar.get(Calendar.YEAR) - 1900.

Returns a value that is the result of subtracting 1900 from the year that contains or begins with the instant in time represented by this Date object, as interpreted in the local time zone.

You should not use deprecated methods. Deprecated methods are methods which should not be used anymore. But whatever the method you're using, read its javadoc to know what it does.

Upvotes: 12

epochengine
epochengine

Reputation: 2062

This is only a guess, but the 111 could be the number of years since 1900. Take a look at documentation/do some tests to verify this (I can't check at the moment)

Upvotes: 3

Related Questions