Question

Right now is 3/15/11 and when I'm calling a new date object:

Date now = new Date();

I'm getting in return

  • the month as 2 (getMonth()),
  • the day as 2 (getDay())
  • and the year (getYear()) as 111.

Is there a reason for this convention?

Was it helpful?

Solution

Straight from the class's documentation:

  • A year y is represented by the integer y - 1900.
  • A month is represented by an integer from 0 to 11; 0 is January, 1 is February, and so forth; thus 11 is December.
  • A date (day of month) is represented by an integer from 1 to 31 in the usual manner.

And as for getDay():

Returns the day of the week represented by this date. The returned value (0 = Sunday, 1 = Monday, 2 = Tuesday, 3 = Wednesday, 4 = Thursday, 5 = Friday, 6 = Saturday) represents the day of the week that contains or begins with the instant in time represented by this Date object, as interpreted in the local time zone.

March 15th 2011 is in fact a Tuesday.

OTHER TIPS

Is there a reason for this convention?

The reason is that it is what the javadoc for Date specifies; see @matt b's answer.

The Date APIs were created in the days of JDK 1.0, and are well known to be problematic in a number of areas. That is why most of the Date methods are marked as Deprecated. (By the way, that means that it is recommended that you don't use them in new code!!)

The Calendar APIs are a significant improvement on Date, but the best by far APIs for handling date / time values in Java are the 3rd-party Joda time APIs.


If you want examples of Joda time usage, look at the link above. There's an example of Calendar usage in the GregorianCalendar javadocs. More examples of Calendar usage may be found on this page.

tl;dr

LocalDate                              // Modern class to represent a date-only value, without time-of-day, without time zone or offset-from-UTC.
.now( ZoneId.of( "Africa/Tunis" ) )    // Capture the current date as seen in the wall-clock time used by the people of a specific region (a time zone).
.getYear()                             // Get year number, such as 2019 presently.

…and:

.getMonthValue()                       // Get month number, 1-12 for January-December.

…and:

.getDayOfMonth()                       // Get day-of-month number, 1-31.

Details

Apparently you are using either of two terrible date-time classes, java.util.Date or java.sql.Date. Both are outmoded as of the adoption of JSR 310, defining their replacement, the modern java.time classes.

LocalDate

The LocalDate class represents a date-only value without time-of-day and without time zone or offset-from-UTC.

A time zone is crucial in determining a date. For any given moment, the date varies around the globe by zone. For example, a few minutes after midnight in Paris France is a new day while still “yesterday” in Montréal Québec.

If no time zone is specified, the JVM implicitly applies its current default time zone. That default may change at any moment during runtime(!), so your results may vary. Better to specify your desired/expected time zone explicitly as an argument. If critical, confirm the zone with your user.

Specify a proper time zone name in the format of Continent/Region, such as America/Montreal, Africa/Casablanca, or Pacific/Auckland. Never use the 2-4 letter abbreviation such as EST or IST as they are not true time zones, not standardized, and not even unique(!).

ZoneId z = ZoneId.of( "America/Montreal" ) ;  
LocalDate today = LocalDate.now( z ) ;

If you want to use the JVM’s current default time zone, ask for it and pass as an argument. If omitted, the code becomes ambiguous to read in that we do not know for certain if you intended to use the default or if you, like so many programmers, were unaware of the issue.

ZoneId z = ZoneId.systemDefault() ;  // Get JVM’s current default time zone.

Or specify a date. You may set the month by a number, with sane numbering 1-12 for January-December.

LocalDate ld = LocalDate.of( 1986 , 2 , 23 ) ;  // Years use sane direct numbering (1986 means year 1986). Months use sane numbering, 1-12 for January-December.

Or, better, use the Month enum objects pre-defined, one for each month of the year. Tip: Use these Month objects throughout your codebase rather than a mere integer number to make your code more self-documenting, ensure valid values, and provide type-safety. Ditto for Year & YearMonth.

LocalDate ld = LocalDate.of( 1986 , Month.FEBRUARY , 23 ) ;

Accessing parts of a date

The java.time classes use sane numbering, 1-12 for months, 1-7 for days of the week, the year number such as 2019 is the year 2019, and such.

int year = ld.getYear() ;                 // The year, such as 2019 presently.
int monthNumber = ld.getMonthValue() ;    // Number of the month 1-12 for January-December.
Month month = ld.getMonth() ;             // Get the `Month` enum object, one of a dozen predefined objects (one for each month of the year). 
int dayOfMonth = ld.getDayOfMonth() ;     // Get the day of the month, 1-31. 

About java.time

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

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

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

You may exchange java.time objects directly with your database. Use a JDBC driver compliant with JDBC 4.2 or later. No need for strings, no need for java.sql.* classes.

Where to obtain the java.time classes?

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.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top