Алгоритм расчета недели # от даты с произвольным началом недели? (для iCal)

Я могу найти только алгоритм для получения ISO 8601 недели (неделя начинается в понедельник).

Тем не менее, спецификация iCal говорит

Неделя определяется как семидневный период, начиная с дня недели, определенного как начало недели (см. WKST). Первая неделя календарного года - это первая неделя, которая содержит не менее четырех (4) дней в этом календарном году.

Следовательно, он более сложный, чем ISO 8601, поскольку началом недели может быть любой день недели.

Существует ли алгоритм для определения того, какой номер недели у даты, с настраиваемым днем ​​начала недели?

или... есть функция в iCal4j, которая делает это? Определить неделю от даты?

Спасибо!

Ограничение: я использую язык JVM, который не может расширять класс Java, но я могу вызывать методы Java или создавать экземпляры классов Java.

2 ответа

Решение
  1. Позволять daysInFirstWeek быть числом дней в первой неделе года, которые находятся в январе. Неделя начинается на WKST день. (например, если 1 января WKST день, возвращение 7)

  2. Задавать dayOfYear к n-м дням года ввода даты (например, 1 февраля = 32)

  3. Если dayOfYear меньше или равно daysInFirstWeek

    3.1. если daysInFirstWeek больше или равно 4, weekNo 1, перейдите к шагу 5.

    3.2. Позволять daysInFirstWeekOfLastYear количество дней в первой неделе предыдущего года в январе. Неделя начинается на WKST день.

    3.3. если daysInFirstWeekOfLastYear 4 или в прошлом году високосный год и daysInFirstWeekOfLastYear это 5, weekNo 53, в противном случае weekNo 52, перейдите к шагу 5.

  4. Задавать weekNo в ceiling((dayOfYear - daysInFirstWeek) / 7)

    4.1. если daysInFirstWeek больше или равно 4, приращение weekNo на 1

    4.2. если daysInFirstWeek равно 53 и количество дней в первую неделю (начиная с WKST) января в год inputDateгод + 1 больше или равно 4, установить weekNo до 1

  5. вернуть weekNo

if (input_date < firstDateOfTheYear(WKST, year))
{
    return ((isLeapYear(year-1))?53:52);
}
else
{
    return ((dayOfYear(input_date) - firstDateOfTheYear(WKST, year).day)/7 + 1);
}

firstDateOfTheYear возвращает первую календарную дату с учетом начала недели (WKST) и года, например, если WKST = четверг, год = 2012, то возвращается 5 января.

dayOfYear возвращает порядковый числовой день года, например, 1 февраля = 32

Пример № 1: 18 января 2012 года, начало недели - понедельник

  • dayOfYear(18 января 2012 г.) = 18
  • firstDateOfTheYear (Monday, 2012) = 2 января 2012

(18 - 2) / 7 + 1 = 3 Ответ Неделя №. 3

Пример №2: 18 января 2012 года, начало недели - четверг

  • dayOfYear(18 января 2012 г.) = 18
  • firstDateOfTheYear (четверг, 2012) = 5 января 2012

(18 - 5) / 7 + 1 = 2 Ответ Неделя №. 2

Пример № 3: 1 января 2012 года, начало недели - понедельник

  • firstDateOfTheYear (Monday, 2012) = 2 января 2012
  • IsLeapYear (2012-1) = false

1 января 2012 г.<2 января 2012 г. Ответ Неделя №. 52

Другие вопросы по тегам