В чем разница между Calendar.WEEK_OF_MONTH и Calendar.DAY_OF_WEEK_IN_MONTH в классе Java Calendar?

Класс Java Calendar предоставляет два поля: WEEK_OF_MONTH и DAY_OF_WEEK_IN_MONTH. Может кто-нибудь объяснить мне разницу? Кажется, что оба они возвращают одинаковое значение при тестировании, используя следующий код:

Calendar date = Calendar.getInstance();
date.set(2011,5,29);
int weekNo1 = date.get(Calendar.WEEK_OF_MONTH);
int weekNo2 = date.get(Calendar.DAY_OF_WEEK_IN_MONTH);

Ответ 1

Неделя месяца - это неделя в течение текущего месяца, начиная с воскресенья, сколько недель было.

День недели месяца - это день 5, будет четверг, 1 воскресенья и т.д.

Ответ 2

  • Calendar.WEEK_OF_MONTH просто возвращает номер текущей недели в текущем месяце
  • Calendar.DAY_OF_WEEK просто возвращает "Текущий номер дня на текущей неделе, начиная с последнего воскресенья"
  • Calendar.DAY_OF_WEEK_IN_MONTH возвращает "N, если текущий день - N-й день месяца. say " 3, если сегодня третья среда месяца

Итак, я пишу это 21-го декабря 2016 года:

введите описание изображения здесь

И вот что я получаю:

Calendar today = Calendar.getInstance();
System.out.println(today.get(Calendar.DAY_OF_WEEK));          //outputs 4, as today is 4th day in this week which started on 18
System.out.println(today.get(Calendar.DAY_OF_WEEK_IN_MONTH)); //outputs 3, as today is "3rd Wednesday of this month". Earlier two wednesday were on 7th and 14th
System.out.println(today.get(Calendar.WEEK_OF_MONTH));        //outputs 4, as currently 4th week of a month is running

Ответ 3

Разница заключается в том, что DAY_OF_WEEK_IN_MONTH предоставляет количество раз, когда день недели произошел в течение месяца, а WEEK_OF_MONTH просто возвращает номер недели в текущем месяце. Подумайте об этом таким образом, если месяц начнется в среду, первый понедельник будет происходить в течение второй недели месяца. Значение для DAY_OF_WEEK_IN_MONTH для этого понедельника будет равно 1, но WEEK_OF_MONTH будет равно 2.

Ответ 4

Я обнаружил, что все другие документы запутаны, поэтому для любых разработчиков Microsoft, таких как я, это может быть ясно для вас, как и для меня:

http://msdn.microsoft.com/en-us/library/aa986432(v=vs.80).aspx

Константа, представляющая значение для того, сколько раз в данный день произошло в течение месяца.

Ответ 5

Вы также должны учитывать, что Calendar.getInstance зависит от локали. Поэтому иногда может потребоваться указать конкретную локаль вместо локали по умолчанию, например: Calendar.getInstance (новая локаль ("es", "PE").

Например, avobe, Calendar.getInstance (новая локаль ("es", "PE") календарь будет считать первые дни недели понедельниками, в других локалях могут быть другие дни.

Ответ 6

ТЛ; др

  • Calendar.WEEK_OF_MONTH
    • Устаревший, никогда не используйте Calendar.
    • Означает девятую неделю в течение месяца с определением, изменяющимся на Locale и результатом getFirstDayOfWeek().
    • Если вы хотите определить неделю, поскольку неделя месяца # 1 - это неделя, содержащая день месяца 1, используйте: LocalDate::get( ChronoField.ALIGNED_WEEK_OF_MONTH )
  • Calendar.DAY_OF_WEEK_IN_MONTH
    • Устаревший, никогда не используйте Calendar.
    • Означает n-й день недели в этом месяце, например, 2-й вторник, где недели определяются как неделя № 1, содержащая день 1 этого месяца.
    • Заменено LocalDate::get( ChronoField.ALIGNED_DAY_OF_WEEK_IN_MONTH )

Избегайте унаследованного класса Calendar

Помните, что класс Calendar, использованный в этом вопросе, ужасен и был вытеснен несколько лет назад современными классами java.time, определенными в JSR 310. Не используйте ни Calendar, ни GregorianCalendar. Они были разработаны людьми, которые не понимали обработку даты и времени.

java.time

LocalDate

Класс LocalDate представляет значение только для даты без времени суток и без часового пояса или смещения от UTC.

LocalDate ld = LocalDate.of( 2020 , Month.JANUARY , 23 ) ;  // 2020-01-23.

Преобразовать

Если дан объект Calendar, который действительно является GregorianCalendar, вы можете легко преобразовать его в современный объект ZonedDateTime.

GregorianCalendar gc = ( GregorianCalendar ) myCalendar ;  // Cast from more general class to the concrete class underlying.
ZonedDateTime zdt = gc.toZonedDateTime() ;

Извлечь часть только для даты.

LocalDate ld = zdt.toLocalDate() ;  // Extract the date, omitting the time-of-day and the context of a time zone.

ChronoField

Вы можете опросить объект LocalDate с помощью метода get с различными объектами перечисления ChronoField.

Calendar.WEEK_OF_MONTH

Это требует недели месяца. Но как вы определяете неделю месяца? К сожалению, определение класса Calendar варьируется в зависимости от Locale. Таким образом, ваши результаты могут отличаться во время выполнения.

Если вы определили, что неделя № 1 имеет первый день календарного месяца, вы можете опросить LocalDate, используя ChronoField.ALIGNED_WEEK_OF_MONTH.

int weekOfMonth = ld.get( ChronoField.ALIGNED_WEEK_OF_MONTH ) ;

Calendar.DAY_OF_WEEK_IN_MONTH

Это означает n-й день недели, найденный в месяце, например, 2-вторник или 3-й четверг. В отличие от Calendar.WEEK_OF_MONTH, это определение не зависит от Locale. Неделя № 1 - это неделя, содержащая день месяца 1. Этот унаследованный класс Calendar действительно ужасный беспорядок, запутанный и противоречивый. Хорошее избавление.

Теперь в java.time используйте вместо этого ChronoField.ALIGNED_DAY_OF_WEEK_IN_MONTH.

DayOfWeek dow = ld.getDayOfMonth() ;  // Get enum object representing day of week such as 'DayOfWeek.MONDAY'. 
int nthDayOfWeekOfMonth = ld.get( ChronoField.ALIGNED_DAY_OF_WEEK_IN_MONTH ) ;