Question

I need to determine the current year in Java as an integer. I could just use java.util.Date(), but it is deprecated.

Was it helpful?

Solution

int year = Calendar.getInstance().get(Calendar.YEAR);

Not sure if this meets with the criteria of not setting up a new Calendar? (Why the opposition to doing so?)

OTHER TIPS

Using Java 8's time API (assuming you are happy to get the year in your system's default time zone), you could use the Year::now method:

int year = Year.now().getValue();

This simplest (using Calendar, sorry) is:

 int year = Calendar.getInstance().get(Calendar.YEAR);

There is also the new Date and Time API JSR, as well as Joda Time

The easiest way is to get the year from Calendar.

// year is stored as a static member
int year = Calendar.getInstance().get(Calendar.YEAR);

If you want the year of any date object, I used the following method:

public static int getYearFromDate(Date date) {
    int result = -1;
    if (date != null) {
        Calendar cal = Calendar.getInstance();
        cal.setTime(date);
        result = cal.get(Calendar.YEAR);
    }
    return result;
}

You can also use 2 methods from java.time.YearMonth( Since Java 8 ):

import java.time.YearMonth;
...
int year = YearMonth.now().getYear();
int month = YearMonth.now().getMonthValue();

tl;dr

ZonedDateTime.now(  ZoneId.of( "Africa/Casablanca" )  )
             .getYear()

Time Zone

The answer by Raffi Khatchadourian wisely shows how to use the new java.time package in Java 8. But that answer fails to address the critical issue of time zone in determining a date.

int year = LocalDate.now().getYear();

That code depends on the JVM's current default time zone. The default zone is used in determining what today’s date is. Remember, for example, that in the moment after midnight in Paris the date in Montréal is still 'yesterday'.

So your results may vary by what machine it runs on, a user/admin changing the host OS time zone, or any Java code at any moment changing the JVM's current default. Better to specify the time zone.

By the way, always use proper time zone names as defined by the IANA. Never use the 3-4 letter codes that are neither standardized nor unique.

java.time

Example in java.time of Java 8.

int year = ZonedDateTime.now(  ZoneId.of( "Africa/Casablanca" )  ).getYear() ;

Joda-Time

Some idea as above, but using the Joda-Time 2.7 library.

int year = DateTime.now( DateTimeZone.forID( "Africa/Casablanca" ) ).getYear() ;

Incrementing/Decrementing Year

If your goal is to jump a year at a time, no need to extract the year number. Both Joda-Time and java.time have methods for adding/subtracting a year at a time. And those methods are smart, handling Daylight Saving Time and other anomalies.

Example in Joda-Time 2.7.

DateTime oneYearAgo = DateTime.now( DateTimeZone.forID( "Africa/Casablanca" ) ).minusYears( 1 ) ;

If your application is making heavy use of Date and Calendar objects, you really should use Joda Time, because java.util.Date is mutable. java.util.Calendar has performance problems when its fields get updated, and is clunky for datetime arithmetic.

You can also use Java 8's LocalDate:

import java.time.LocalDate;
//...
int year = LocalDate.now().getYear();

As some people answered above:

If you want to use the variable later, better use:

int year;

year = Calendar.getInstance().get(Calendar.YEAR);

If you need the year for just a condition you better use:

Calendar.getInstance().get(Calendar.YEAR)

For example using it in a do while that checks introduced year is not less than the current year-200 or more than the current year (Could be birth year):

import java.util.Calendar;
import java.util.Scanner;

public static void main (String[] args){

    Scanner scannernumber = new Scanner(System.in);
    int year;

    /*Checks that the year is not higher than the current year, and not less than the current year - 200 years.*/

    do{
        System.out.print("Year (Between "+((Calendar.getInstance().get(Calendar.YEAR))-200)+" and "+Calendar.getInstance().get(Calendar.YEAR)+") : ");
        year = scannernumber.nextInt();
    }while(year < ((Calendar.getInstance().get(Calendar.YEAR))-200) || year > Calendar.getInstance().get(Calendar.YEAR));
}

You can do the whole thing using Integer math without needing to instantiate a calendar:

return (System.currentTimeMillis()/1000/3600/24/365.25 +1970);

May be off for an hour or two at new year but I don't get the impression that is an issue?

I use special functions in my library to work with days/month/year ints -

int[] int_dmy( long timestamp ) // remember month is [0..11] !!!
{
  Calendar cal = new GregorianCalendar(); cal.setTimeInMillis( timestamp );
  return new int[] { 
    cal.get( Calendar.DATE ), cal.get( Calendar.MONTH ), cal.get( Calendar.YEAR )
  };
};


int[] int_dmy( Date d ) { 
 ...
}
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top