Как получить день недели ISO с помощью API календаря

Я хочу получить день недели ISO с помощью API Calendar, но он возвращает неверный номер дня.

Воскресенье — это последний день недели, и он должен иметь номер 7 по стандарту ISO, а понедельник — первый день с номером 1.

Но запуск следующего кода для воскресенья (2017-07-30) возвращает мне номер 1. Почему Calendar API возвращает мне другое значение?

Calendar cal = Calendar.getInstance(Locale.US);
cal.set(Calendar.YEAR, 2017);
cal.set(Calendar.MONTH, Calendar.JULY);
cal.set(Calendar.DAY_OF_MONTH, 30);
cal.set(Calendar.HOUR_OF_DAY, 0);
cal.set(Calendar.MINUTE, 0);
cal.set(Calendar.SECOND, 0);
cal.set(Calendar.MILLISECOND, 0);
int dayOfWeek = cal.get(Calendar.DAY_OF_WEEK);

System.out.println(dayOfWeek);

Результат: 1

Я пробовал использовать Joda Time, и это сработало нормально, но мне нужно сделать это с помощью Calendar и Java 6, поэтому использование другой библиотеки не является решением.


person Evandro Pomatti    schedule 04.08.2017    source источник


Ответы (3)


Константы int начинаются с воскресенья и заканчиваются субботой.

Документировано в java.util.Calendar JavaDoc для Java 6.

Поэтому мое предложение - рассчитать его самостоятельно.

person Maia    schedule 04.08.2017
comment
Конечно, ты прав. Нет перечисления, константы. Я изменил ответ в соответствии с этим. - person Maia; 07.08.2017

tl;dr

Устаревший способ определения номера дня недели, определенный ISO 8601 (понедельник-воскресенье, 1-7):

int dayOfWeekISO = cal.get( Calendar.DAY_OF_WEEK ) - 1 ;
if( dayOfWeekISO == 0 ) {  // For Sunday ( 1 - 1 = 0), add 7. 
    dayOfWeekISO = ( dayOfWeekISO + 1 ) ; 
}

Современный способ:

LocalDate.of( 2017 , Month.JULY , 30 )  // Date-only value.
         .getDayOfWeek()                // `DayOfWeek.SUNDAY` enum object.
         .getValue()                    // 7 for Sunday. (1 = Monday, per ISO 8601 standard.)

7

Подробности

Правильный принятый ответ Майи: Эти int константы на Calendar определяют неделю как 1–7 для воскресенье – суббота, как принято в США.

ДЕНЬ НЕДЕЛИ

общедоступный статический финал через DAY_OF_WEEK

Номер поля для получения и установки с указанием дня недели. Это поле принимает значения ВОСКРЕСЕНЬЕ, ПОНЕДЕЛЬНИК, ВТОРНИК, СРЕДА, ЧЕТВЕРГ, ПЯТНИЦА и СУББОТА.

Если вы абсолютно не можете добавить библиотеку, то вы должны изменить определение недели с Calendar на воскресенье-субботу с 1 по 7. Чтобы поставить Деньги на первое место, вычтите 1, затем проверьте наличие 0, к которому вы прибавляете 7.

int dayOfWeekISO = cal.get( Calendar.DAY_OF_WEEK ) - 1 ;
if( dayOfWeekISO == 0 ) {  // For Sunday ( 1 - 1 = 0), add 7. 
    dayOfWeekISO = ( dayOfWeekISO + 1 ) ; 
}

Кстати, чтобы пойти другим путем, от стиля ISO 8601 до стиля США (воскресенье первое ), рассчитайте по модулю 7, затем прибавьте 1.

( DayOfWeek.SUNDAY.getValue() % 7 ) + 1

Нравится:

System.out.println( ( DayOfWeek.SUNDAY.getValue() % 7 ) + 1 ) ;
System.out.println( ( DayOfWeek.MONDAY.getValue() % 7 ) + 1 ) ;
System.out.println( ( DayOfWeek.TUESDAY.getValue() % 7 ) + 1 ) ;
System.out.println( ( DayOfWeek.WEDNESDAY.getValue() % 7 ) + 1 ) ;
System.out.println( ( DayOfWeek.THURSDAY.getValue() % 7 ) + 1 ) ;
System.out.println( ( DayOfWeek.FRIDAY.getValue() % 7 ) + 1 ) ;
System.out.println( ( DayOfWeek.SATURDAY.getValue() % 7 ) + 1 ) ;

1

2

3

4

5

6

7

Но рассмотрите возможность добавления библиотеки современных классов даты и времени. Стоит добавить банку в свой проект. Эти старые классы свиданий действительно убогие.

Избегайте устаревших классов даты и времени

Класс Calendar является частью проблемных старых устаревших классов даты и времени, которые теперь вытеснены классами java.time.

Java.время

Перечисление java.time.DayOfWeek является стандартным и представляет неделя определяется ISO 8601, где неделя длится с понедельника по воскресенье, пронумерована от 1 до 7. .

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

LocalDate ld = LocalDate.of( 2017 , Month.JULY , 30 ) ;
DayOfWeek dow = ld.getDayOfWeek() ;
int dowNumber = dow.getValue() ;
String output = dow.getDisplayName( TextStyle.FULL , Locale.CANADA_FRENCH ) ; 

См. выполнение этого кода на сайте IdeOne.com.

ld.toString(): 30 июля 2017 г.

dow.toString(): ВОСКРЕСЕНЬЕ

внизНомер: 7

выходной: воскресенье


О java.time

Платформа java.time встроен в Java 8 и более поздние версии. Эти классы заменяют проблемные старые устаревшие классы даты и времени, такие как java.util.Date, Calendar и SimpleDateFormat.

Проект Joda-Time, теперь в режим обслуживания, советует перейти на java.time.

Чтобы узнать больше, см. учебник по Oracle. И поищите множество примеров и пояснений в Stack Overflow. Спецификация: JSR 310.

Где получить классы java.time?

Проект ThreeTen-Extra расширяет java.time дополнительными классами. . Этот проект является испытательным полигоном для возможных дополнений к java.time в будущем. Здесь вы можете найти несколько полезных классов, таких как Interval, YearWeek, YearQuarter и подробнее.

person Basil Bourque    schedule 05.08.2017

Проверьте Javadoc Календаря для Java 6, прежде чем публиковать вопрос значения констант в календаре

Значение Calendar.SUNDAY равно 1 для языкового стандарта США.

person Harish Barma    schedule 04.08.2017
comment
Значение Calendar.SUNDAY всегда одинаково и не зависит от локали. - person Igor Rodriguez; 09.01.2018
comment
Calendar.sunday не изменяется в зависимости от локали, но день недели, поскольку 1 будет меняться в зависимости от локали. Прошу прощения за расплывчатый ответ, но у меня другое намерение - person Harish Barma; 09.01.2018