вычислить количество недель в данном году

Я хотел бы получить количество недель в любой данный год. Хотя 52 принимается в качестве обобщенного Всемирного ответа, календари для 2015, 2020 и 2026 на самом деле есть 53 недель.

есть ли способ, которым я могу вычислить это, или какие-либо функции, которые помогут мне?

8 ответов


согласно статье Википедии о формат даты недели ISO, вы можете рассчитать его, используя следующий код.

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

вы можете закодировать себя со следующей информацией из дата недели ISO.

в среднем, в году 53 недели каждые 5,6 лет.

следующие 71 год в 400-летнем цикле (добавить 2000 для текущих лет) имеют 53 недели. Годы не перечислены у 52 недель.

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.

вы можете использовать вышеуказанную информацию для возврата 52 или 53 соответственно:)


быстрый вкладыш 2:

Calendar calendar = Calendar.getInstance();
Integer weeksOfYear = calendar.getActualMaximum(Calendar.WEEK_OF_YEAR);

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

Я хотел бы дать свой взгляд на использование нового API даты в Java 8 со следующим готовым к запуску кодом:

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");
        }
    }
}

выход:

2004 имеет 53 недели
2009 имеет 53 недели
2015 имеет 53 недели
2020 имеет 53 недели
2026 имеет 53 недели
2032 имеет 53 недели
...

и так далее...

на date.withDayOfMonth(1).withMonth(6); трюк заключается в том, что опущение этого приводит к немного другому выходу, если LocalDate.of(year, 1, 1) передается:

2004 имеет 53 недели
2005 имеет 53 недели
...

Я все еще новичок в API даты Java 8, но я уверен, что это поведение связано с тем, что 2005-01-01 является частью Недели 53 2014. Это делает date.range(WeekFields.ISO.weekOfWeekBasedYear()).getMaximum() верните количество недель для недели на основе года 2014.


ссылка на ответ

gregorianCalendar.set(year, 12, 31);
int totalWeeks = gregorianCalendar.getMaximum(Calendar.WEEK_OF_YEAR);

@Manjula Weerasinge ответ на самом деле ввести ошибку для 2016. Вот лучшее решение.

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;
}

этот метод вычисляет количество недель в год ISO с помощью библиотеки времени Joda.

    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();
    }