I would like to get the number of weeks in any given year. Even though 52
is accepted as a generalised worldwide answer, the calendars for 2015
,
Link to answer
gregorianCalendar.set(year, 12, 31);
int totalWeeks = gregorianCalendar.getMaximum(Calendar.WEEK_OF_YEAR);
According to the wikipedia article on ISO week date format, You can calculate it using following code.
Calendar cal = Calendar.getInstance();
cal.set(Calendar.YEAR, 2015);
cal.set(Calendar.MONTH, Calendar.DECEMBER);
cal.set(Calendar.DAY_OF_MONTH, 31);
int ordinalDay = cal.get(Calendar.DAY_OF_YEAR);
int weekDay = cal.get(Calendar.DAY_OF_WEEK) - 1; // Sunday = 0
int numberOfWeeks = (ordinalDay - weekDay + 10) / 7;
System.out.println(numberOfWeeks);
Update:
Seems the answer from @Samuel https://stackoverflow.com/a/40174287/201986 is better and free from the bug mentioned by Luca
You can code yourself with the following information from ISO week date.
On average, a year has 53 weeks every 5.6 years.
The following 71 years in a 400-year cycle (add 2000 for current years) have 53 weeks. Years not listed have 52 weeks.
004, 009, 015, 020, 026, 032, 037, 043, 048, 054, 060, 065, 071, 076, 082, 088, 093, 099, 105, 111, 116, 122, 128, 133, 139, 144, 150, 156, 161, 167, 172, 178, 184, 189, 195, 201, 207, 212, 218, 224, 229, 235, 240, 246, 252, 257, 263, 268, 274, 280, 285, 291, 296, 303, 308, 314, 320, 325, 331, 336, 342, 348, 353, 359, 364, 370, 376, 381, 387, 392, 398.
You can use the above information to return 52 or 53 accordingly :)
Quick one liner:
Integer weeksOfYear = Calendar.getInstance().getActualMaximum(Calendar.WEEK_OF_YEAR);
I would like to give my take on usage of the new Date API in Java 8 with the following ready to run code:
private static long getNumberOfWeeksInYear(LocalDate date) {
LocalDate middleOfYear = date.withDayOfMonth(1).withMonth(6);
return middleOfYear.range(WeekFields.ISO.weekOfWeekBasedYear()).getMaximum();
}
public static void main(String[] args) {
for (int year = 2000; year < 2400; year++) {
long numberOfWeeks = getNumberOfWeeksInYear(LocalDate.of(year, 1, 1));
if (numberOfWeeks != 52) {
System.out.println(year + " has " + numberOfWeeks + " weeks");
}
}
}
The output is:
2004 has 53 weeks
2009 has 53 weeks
2015 has 53 weeks
2020 has 53 weeks
2026 has 53 weeks
2032 has 53 weeks
...
And so on...
The date.withDayOfMonth(1).withMonth(6);
trick is because omitting this results in slightly different output if LocalDate.of(year, 1, 1)
is passed:
2004 has 53 weeks
2005 has 53 weeks
...
I am still new to the Java 8 date API, but my I am pretty sure this behaviour is becuase 2005-01-01 is part of week 53 of 2014. This makes date.range(WeekFields.ISO.weekOfWeekBasedYear()).getMaximum()
return the number of weeks for the week based year of 2014.
Calendar cal = Calendar.getInstance();
cal.set(Calendar.YEAR, 2015);
cal.set(Calendar.MONTH, Calendar.DECEMBER);
cal.set(Calendar.DAY_OF_MONTH, 31);
System.out.println(cal.get(Calendar.WEEK_OF_YEAR));