2

So, I'm typing a very simple program to accept the date from the user and print it back to them. On my first attempt, i saw that the year gets incremented by 1900. What exactly is the reason? I also see that the month value is being incremented by one. Here is the program block

Date dateInput = new Date(114,2,20,13,18,48); //2014-1900 = 114
System.out.println("Date Entered by You : ");
System.out.println(dateInput);

The output for this is

Date Entered by You : 
Thu Mar 20 13:18:48 IST 2014

I entered the month value as 2, but it it printing at as March. What could be the problem? And why is the Date class preprogrammed to add a 1900 to the entered year?

woodhead92
  • 117
  • 1
  • 3
  • 8
  • 1
    Why don't you read the javadoc of the Date class. It has all the explanations you need. And it will tell you what to use instead of this deprecated constructor. – JB Nizet Feb 21 '14 at 07:58
  • 2
    I'd like to have a fairly robust conversation with the Java team who decided to zero-base the months. It's at odds with ISO month counting for starters. The confusion is not your fault IMO, so +1. – Bathsheba Feb 21 '14 at 08:02
  • 1
    everyone knows that month are indexed with 0-11 but it would be interesting to know if anyone here can answer why we shouldnt creat a date before 1900. why didnt the api want that? – kai Feb 21 '14 at 08:03
  • @Bathsheba Yeah. Thats what confused me. The date wasnt zero based, so i assumed the months wouldn't be zero based too. Shouldve checked the Date API though. – woodhead92 Feb 21 '14 at 08:16
  • FYI, the troublesome old date-time classes such as [`java.util.Date`](https://docs.oracle.com/javase/9/docs/api/java/util/Date.html), [`java.util.Calendar`](https://docs.oracle.com/javase/9/docs/api/java/util/Calendar.html), and `java.text.SimpleDateFormat` are now [legacy](https://en.wikipedia.org/wiki/Legacy_system), supplanted by the [java.time](https://docs.oracle.com/javase/9/docs/api/java/time/package-summary.html) classes built into Java 8 & Java 9. See [Tutorial by Oracle](https://docs.oracle.com/javase/tutorial/datetime/TOC.html). – Basil Bourque Feb 07 '18 at 01:12

4 Answers4

6

Check the Date API

A month is represented by an integer from 0 to 11; 0 is January, 1 is February, and so forth; thus 11 is December.


I entered the month value as 2, but it it printing at as March. What could be the problem?

So as per api, in your case, it's March.

On my first attempt, i saw that the year gets incremented by 1900. What exactly is the reason?

You have used depreciated Date(int year, int month, int date, int hrs, int min, int sec) Constructor, and it's says

As of JDK version 1.1, replaced by Calendar.set(year + 1900, month, date, hrs, min, sec) or GregorianCalendar(year + 1900, month, date, hrs, min, sec). Allocates a Date object and initializes it so that it represents the instant at the start of the second specified by the year, month, date, hrs, min, and sec arguments, in the local time zone.


And, It's just part of the horrendous mess which is the Java date/time API. Month starts with zero, but, day starts with 1. In Java 8, the new java.time.* package (defined by JSR-310 and inspired by Joda-Time) fixes this problem and more.

Abimaran Kugathasan
  • 31,165
  • 11
  • 75
  • 105
3

The month index start from 0-January 1 febuary ans so on 11 for december

Chirag Sutariya
  • 352
  • 1
  • 11
1

This is Date source code:

public Date(int year, int month, int date, int hrs, int min, int sec) {
    int y = year + 1900;
    // month is 0-based. So we have to normalize month to support Long.MAX_VALUE.
    if (month >= 12) {
        y += month / 12;
        month %= 12;
    } else if (month < 0) {
        y += CalendarUtils.floorDivide(month, 12);
        month = CalendarUtils.mod(month, 12);
    }
    BaseCalendar cal = getCalendarSystem(y);
    cdate = (BaseCalendar.Date) cal.newCalendarDate(TimeZone.getDefaultRef());
    cdate.setNormalizedDate(y, month + 1, date).setTimeOfDay(hrs, min, sec, 0);
    getTimeImpl();
    cdate = null;
}

Month start with Jan-0, Feb-1...

In above source code you can find why you have to subtract 1900.

Rahul
  • 3,479
  • 3
  • 16
  • 28
0

tl;dr

ZonedDateTime.of( 2014 , 2 , 20 , 13 , 18 , 48 , 0 , ZoneId.of( "Pacific/Auckland" ) )

2014-02-20T13:18:48+05:30[Asia/Kolkata]

java.time

Use modern java.time classes that have sane numbering. Avoid the troublesome poorly-designed old date-time classes that are now legacy, supplanted by the java.time classes.

No crazy numbering in java.time:

  • 2014 means the year 2014. No funky math with 1900.
  • 2 means February, 1-12 for January-December.
  • 1 means Monday, 1-7 for Monday-Sunday per ISO 8601 standard.

So, if you want early afternoon on March 20, 2014 in India time zone:

ZoneId z = ZoneId.of( "Asia/Kolkata" ) ;
ZonedDateTime zdt = ZonedDateTime.of( 2014 , 2 , 20 , 13 , 18 , 48 , 0 , z ) ;

zdt.toString(): 2014-02-20T13:18:48+05:30[Asia/Kolkata]

Or build in pieces.

LocalDate ld = LocalDate.of( 2014 , 2 , 20 ) ;
LocalTime lt = LocalTime.of( 13 , 18 , 48 ) ;
ZoneId z = ZoneId.of( "Asia/Kolkata" ) ;
ZonedDateTime zdt = ZonedDateTime.of( ld , lt , z ) ;

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.

LocalDate ld = LocalDate.of( 2014 , Month.FEBRUARY , 20 ) ;

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


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.

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

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

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.

Basil Bourque
  • 303,325
  • 100
  • 852
  • 1,154