Подтвердить что ты не робот

Какая разница между добавлением DAY_OF_MONTH или DAY_OF_YEAR к объекту календаря?

Я хочу увеличить определенную дату на 1 день. Я создаю объект Calendar, например:

Calendar cal = Calendar.getInstance();
cal.set(Calendar.YEAR, 2012);
cal.set(Calendar.MONTH, 0);
cal.set(Calendar.DAY_OF_MONTH, 31);

Затем, чтобы увеличить его на 1 день, я могу сделать 2 вещи:

cal.add(Calendar.DAY_OF_MONTH, 1);

ИЛИ

cal.add(Calendar.DAY_OF_YEAR, 1);

Существуют и другие константы "Дня", но я получаю тот же результат, используя вышеприведенные 2 метода увеличения дня на 1. В каком случае я получу разные результаты для двух?

4b9b3361

Ответ 1

Для добавления это действительно не имеет значения, но это

Calendar c = Calendar.getInstance();
System.out.println(c.get(Calendar.DAY_OF_MONTH));
System.out.println(c.get(Calendar.DAY_OF_YEAR));

печатает

28
363

Ответ 2

Calendar.add Добавляет или вычитает указанное количество времени в данное поле календаря на основе правил календаря.

Здесь у вас есть список полей календаря, которые вы можете добавить или вычесть:

  • MILLISECOND - это количество миллисекунд от 0 до 999

  • SECOND - количество секунд от 0 до 59

  • MINUTE - количество минут от 0 до 59

  • HOUR - это количество часов от 0 до 11

  • HOUR_OF_DAY - количество часов от 0 до 23

  • DAY_OF_WEEK - день относительно недели между 1 и 7

  • DAY_OF_MONTH - день по отношению к месяцу между 1 и 31

  • DAY_OF_YEAR - день относительно года между 1 и 365

  • WEEK_OF_MONTH - неделя по отношению к месяцу, начиная с 1

  • WEEK_OF_YEAR - неделя по отношению к году, начиная с 1

  • MONTH - это месяц относительно года между 0 и 11

  • YEAR - количество лет, начиная с 1

Часы, дни и недели имеют несколько полей, но не имеет значения, какое из них вы выберете 1. Например, использование -8 для DAY_OF_WEEK будет работать.

calendar.add(Calendar.DAY_OF_MONTH, -2); // subtract 2 days
calendar.add(Calendar.DAY_OF_WEEK, -2);  // subtract 2 days
calendar.add(Calendar.DAY_OF_YEAR, -2);  // subtract 2 days

calendar.add(Calendar.YEAR, -2);         // subtract 2 years

1Не имеет значения только использование Calendar.add, с другими операциями результаты могут отличаться.

Ответ 3

Используйте Calendar.DATE для своих целей. В вашем случае эти три константы являются синонимами.

Ответ 4

Это не имеет никакого значения, когда вы вызываете add. Однако получатели возвращают разные результаты: D

фрагмент кода из GregorianCalendar#add

case DAY_OF_MONTH: // synonym of DATE
 case DAY_OF_YEAR:
 case DAY_OF_WEEK:
    break;

Ответ 5

DAY_OF_YEAR

Номер поля для получения и установки, указывающий номер дня в текущем году

DAY_OF_MONTH

Номер поля для получения и установки, указывающий день месяца. Это синоним DATE

Вы увидите разницу, если день больше 31.

Ответ 6

Вы по существу увеличиваете дату на один, в обоих случаях. Таким образом, нет разницы в обоих подходах.

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

Ответ 7

На самом деле, может быть и будет разница в зависимости от того, какой тип поля вы выберете:

* http://docs.oracle.com/javase/1.5.0/docs/api/java/util/Calendar.html

Модель использования.

Чтобы мотивировать поведение add() и roll(), рассмотрим компонент пользовательского интерфейса с кнопками увеличения и уменьшения для месяц, день и год и базовый GregorianCalendar. Если интерфейс читается 31 января 1999 года, а пользователь нажимает месяц кнопку увеличения, что он должен читать? Если основной реализация использует set(), это может быть прочитано 3 марта 1999 года. Лучше результатом будет 28 февраля 1999 года. Кроме того, если пользователь нажимает кнопку приращения месяца, она должна быть прочитана 31 марта 1999 г., а не 28 марта 1999 года. Сохраняя исходную дату и используя либо add(), либо roll(), в зависимости от того, должны ли быть затронуты большие поля, пользовательский интерфейс может вести себя так, как будет ожидать большинство пользователей.

Ответ 8

ТЛ; др

LocalDate.of( 2012 , Month.JANUARY , 31 )
    .plusDays( 1 )

2012-02-01

…или же…

LocalDate.of( 2012 , 1 , 31 )  // Sane numbering: 1-12 for January-December, and '2012' means year 2012.
    .plusDays( 1 )

2012-02-01

java.time

Класс Calendar сбивает с толку, неуклюж, и плохо разработан. Среди многих проблем - методы передачи флага. К счастью, теперь вы можете забыть все об этом классе.

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

LocalDate

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

Часовой пояс имеет решающее значение при определении даты. В любой момент времени дата меняется по всему земному шару в зависимости от зоны. Например, через несколько минут после полуночи в Париже Франция - новый день, а в Монреале-Квебеке все еще "вчера".

Если часовой пояс не указан, JVM неявно применяет свой текущий часовой пояс по умолчанию. Это значение по умолчанию может измениться в любой момент, поэтому ваши результаты могут отличаться. Лучше явно указать желаемый/ожидаемый часовой пояс в качестве аргумента.

Укажите правильное имя часового пояса в формате continent/region, например, America/Montreal, Africa/Casablanca или Pacific/Auckland. Никогда не используйте 3-4-буквенное сокращение, такое как EST или IST поскольку они не являются истинными часовыми поясами, не стандартизированы и даже не уникальны (!).

ZoneId z = ZoneId.of( "America/Montreal" ) ;  
LocalDate today = LocalDate.now( z ) ;

Если вы хотите использовать текущий часовой пояс по умолчанию для JVM, попросите его и передайте в качестве аргумента. Если опущено, текущее значение по умолчанию для JVM применяется неявно. Лучше быть явным, поскольку значение по умолчанию может быть изменено в любой момент во время выполнения любым кодом в любом потоке любого приложения в JVM.

ZoneId z = ZoneId.systemDefault() ;  // Get JVMs current default time zone.

Или укажите дату. Вы можете установить месяц по номеру, с нормальным номером 1-12 для января-декабря.

LocalDate ld = LocalDate.of( 1986 , 2 , 23 ) ;  // Years use sane direct numbering (1986 means year 1986). Months use sane numbering, 1-12 for January-December.

Или, лучше, использовать предварительно определенные объекты перечисления Month, по одному на каждый месяц года. Совет: используйте эти объекты Month всей вашей кодовой базе, а не просто целое число, чтобы сделать ваш код более самодокументированным, обеспечить допустимые значения и обеспечить безопасность типов.

LocalDate ld = LocalDate.of( 1986 , Month.FEBRUARY , 23 ) ;

части

Имея LocalDate в руках, вы можете LocalDate его части.

Чтобы получить день месяца, то есть "дату", например 23 от 23 января 2018 года:

int dayOfMonth = ld.getDayOfMonth() ; // 1-31, depending on length of month.

Чтобы получить n-й день в году, 1-365 или високосный год, 1-366:

int dayOfYear = ld.getDayOfYear() ;

математический

Добавление или вычитание дней довольно просто и интуитивно понятно в java.time. Удобные методы и объекты промежутка времени делают код намного более понятным.

LocalDate dayLater = ld.plusDays( 1 ) ;

Итак, завтрашний день будет:

LocalDate tomorrow = LocalDate.now( ZoneId.of( "Africa/Tunis" ) ).plusDays( 1 ) ;

В качестве альтернативы вы можете представить промежуток времени, не привязанный к временной шкале. Для лет-месяцев-дней используйте Period. Для часов-минут-секунд используйте Duration.

Period p = Period.ofDays( 1 ) ;
LocalDate dayLater = ld.plus( p ) ;

Обратите внимание, что java.time использует разумную нумерацию, в отличие от устаревших классов. Число 2018 - это год 2018. Месяцы с 1 по 12 для января-декабря. Дни недели с понедельника по воскресенье пронумерованы 1-7 в соответствии со стандартом ISO 8601.


О java.time

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

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

Чтобы узнать больше, смотрите Oracle Tutorial. И поиск для многих примеров и объяснений. Спецификация JSR 310.

Где взять классы java.time?

  • Java SE 8, Java SE 9 и более поздние
    • Встроенный.
    • Часть стандартного Java API с комплексной реализацией.
    • Java 9 добавляет некоторые незначительные функции и исправления.
  • Java SE 6 и Java SE 7
    • Большая часть функциональности java.time перенесена на Java 6 и 7 в ThreeTen-Backport.
  • Android

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

Ответ 9

В дополнение к дате не имеет значения, используете ли вы DAY_OF_MONTH или DAY_OF_YEAR. Однако это имеет смысл, когда вы получаете call getter и передаете один из них.

Ответ 10

Использовать DATE или DAY_OF_MONTH оба одинаковы

Вот разница:

DATE or DAY_OF_MONTH : Get and Set indicating the day of the month
DAY_OF_WEEK          : get and set indicating the week number within the current month
DAY_OF_YEAR          : get and set indicating the day number within the current ye

Источник: https://docs.oracle.com/javase/7/docs/api/java/util/Calendar.html