10

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, 2020 and 2026 actually have 53 weeks.

Is there any way that I can calculate this, or any functions that will help me out?

wattostudios
  • 8,666
  • 13
  • 43
  • 57
AndroidGuy
  • 1,270
  • 4
  • 15
  • 32
  • General comment for all which doesn't exactly answer the question above but is useful to know: To understand why the Calendar class returns 53 for "number of weeks in a year" you have to understand how the `getFirstDayOfWeek()` and `getMinimalDaysInFirstWeek()` methods are used in the calculation. If the "first day of the week" is specified as Monday for example and the "minimal days in first week" is 4 and the first Monday of the year is on 5th January, then the week preceding 5th January is classed as part of that year. – Adil Hussain Dec 25 '14 at 11:49

10 Answers10

15

Quick one liner:

Integer weeksOfYear = Calendar.getInstance().getActualMaximum(Calendar.WEEK_OF_YEAR);
Samuel
  • 4,783
  • 3
  • 29
  • 32
  • 2
    It would have been nice to see a more detailed explanation of this method. `getActualMaximum` iteratively counts the total number based on current time, whereas `getMaximum` just returns the maximum value of that field. So `getActualMaximum` is indeed the answer to this question. – Yeti May 16 '17 at 16:28
13

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

Manjula
  • 4,961
  • 3
  • 28
  • 41
  • 1
    thanx Manjula. Somehow my problem was fixed automatically. I think Calendar class doesnt consider week 53. (no idea, what Date format it follows...). But calendar.set(Calendar.WEEK_OF_YEAR, 52); calendar.set(Calendar.YEAR, 2015); SimpleDateFormat formatter = new SimpleDateFormat("ddMMM yyyy"); Date startDate = calendar.getTime(); calendar.add(Calendar.DATE, 6); Date endDate = calendar.getTime(); gives me start & end date for week as 27 Dec2015 & 2nd Jan2016. :) :) (these dates i was expecting for week 53, which was the reason for this question thread.. :) ) – AndroidGuy Jan 04 '12 at 14:35
  • This actually introduce a bug. I just tried it out: for 2016, it return 52, but Calendar consider it having 53 weeks. It actually has 53 weeks because it start with a Thursday. I review your function: I'll post it down below. Please edit your answer in order to remove this bug :) – Luca Nicoletti May 07 '17 at 09:28
  • @KumaresanPerumal this was answered in 2012 (8 years ago :O ). anyway I updated the post to link to current best answer. – Manjula Feb 07 '20 at 04:43
  • I need it in java 8 – Kumaresan Perumal Feb 07 '20 at 07:53
10

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 :)

Community
  • 1
  • 1
COD3BOY
  • 11,964
  • 1
  • 38
  • 56
6

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.

Magnilex
  • 11,584
  • 9
  • 62
  • 84
4
    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));
pap
  • 27,064
  • 6
  • 41
  • 46
2

Link to answer

gregorianCalendar.set(year, 12, 31);
int totalWeeks = gregorianCalendar.getMaximum(Calendar.WEEK_OF_YEAR);
Community
  • 1
  • 1
murt
  • 3,790
  • 4
  • 37
  • 48
2

@Manjula Weerasinge answer actually introduce a bug for 2016. Here's a better solution.

Calendar cal = Calendar.getInstance();
cal.set(Calendar.YEAR, year);
cal.set(Calendar.MONTH, Calendar.JANUARY);
cal.set(Calendar.DAY_OF_MONTH, 1);
GregorianCalendar gregorianCalendar = new GregorianCalendar();

int weekDay = cal.get(Calendar.DAY_OF_WEEK) - 1;
if (gregorianCalendar.isLeapYear(year)){
   if (weekDay == Calendar.THURSDAY || weekDay == Calendar.WEDNESDAY)
      return 53;
   else
      return 52;
} else {
   if (weekDay == Calendar.THURSDAY)
      return 53;
   else
      return 52;
}
Luca Nicoletti
  • 2,265
  • 2
  • 18
  • 32
1

This method calculates the number of weeks a ISO year using the Joda time library.

    import org.joda.time.DateTime;
    import org.joda.time.DateTimeZone;

    public static int weeksInYear(int year) {
        return new DateTime(DateTimeZone.forID("America/Los_Angeles"))
            .withWeekyear(year + 1)
            .withWeekOfWeekyear(1)
            .minusWeeks(1)
            .getWeekOfWeekyear();
    }
0

For ISO date format, we can calculate number of weeks as follows:

int getNoOfWeeks(int year) {
    Calendar cal = Calendar.getInstance();
    cal.set(Calendar.YEAR, year);
    cal.setMinimalDaysInFirstWeek(4);
    cal.set(Calendar.DAY_OF_WEEK, Calendar.MONDAY);
    return cal.getActualMaximum(Calendar.WEEK_OF_YEAR);
}

So, for year = 2018, it will return 52, for 2019, it will also return 52, but for 2020 it will return 53 as ISO year has 52 or 53 weeks.

arifng
  • 726
  • 1
  • 12
  • 22
0

According to ISO standards, a week starts on a Monday and the first week of the year is the week with the first Thursday of the year.

Following this logic, 28th of December always lies in the last week of the year.

long maxWeekInYear(int year) {
    return LocalDate.of(year, 12, 28).get(WeekFields.ISO.weekOfWeekBasedYear());
}

However, some countries have other definitions of a week. The WeekFields class allows one to use a given definition of a week:

long maxWeekInYear(int year, WeekFields weekFields) {
    return LocalDate.of(year, 7, 1).range(weekFields.weekOfWeekBasedYear()).getMaximum();
}

For instance, in the US, a week starts on Sunday and the minimum number of days in the first week of the year is 4. WeekFields.of(DayOfWeek.SUNDAY, 4) can be used to determine the number of weeks according to US rules. This is consistent with the results from Savvytime.com.

MC Emperor
  • 22,334
  • 15
  • 80
  • 130