1. Переход от класса Date к классу Calendar

Программисты любили класс Date за его простоту и поддержку стандартов Unix, но, как известно, наши недостатки — это продолжение наших достоинств.
Программисты хотели иметь «умный класс Date». И такой класс появился: им стал класс Calendar. Он задумывался как инструмент не только хранения, но и сложной работы с датами.
Полное имя класса Calendar — java.util.Calendar. Не забывайте добавлять его в import, если решите использовать в своем коде.
Создать объект Calendar можно командой:
Calendar date = Calendar.getInstance();
Статический метод getInstance() класса Calendar создаст объект Calendar, инициализированный текущей датой. В зависимости от настроек компьютера, на котором выполняется программа, будет создан нужный календарь.
Более правильно было бы сказать — актуальный. Дело в том, что на Земле не один, а много календарей. И почти каждый из них связан с какой-нибудь религией или страной. Класс Calendar поддерживает 3 из них:
| Календарь | Описание |
|---|---|
| GregorianCalendar | Христианский Григорианский календарь |
| BuddhistCalendar | Буддистский календарь |
| JapaneseImperialCalendar | Японский Императорский календарь |
А ведь есть еще Китайский и Арабский календари. В общем, работа со временем не такая простая, как кажется.
В Китае на момент написания этой лекции официально 4716 год. А по мусульманскому календарю — 1398. Добро пожаловать в большой мир, мой друг-программист.
2. Создание объекта календарь
Мы будем использовать Григорианский календарь как самый распространенный в мире. По крайней мере, пока Китай не купит компанию Oracle и не сделает свой календарь основным.
Объект календарь с произвольной датой создается командой:
Calendar date = new GregorianCalendar(год, месяц, день);
Да, каждый раз придется писать GregorianCalendar. Можно и вместо Calendar писать GregorianCalendar: так тоже будет работать. Но просто Calendar писать короче.
Год нужно писать полностью: никаких 19 вместо 2019. Месяцы по-прежнему нумеруются с нуля. А дни месяца по-прежнему нумеруются не с нуля (слабаки!).
Чтобы задать не только дату, но и время, нужно передать их дополнительными параметрами:
... = new GregorianCalendar(год, месяц, день, часы, минуты, секунды);
Можно даже передать миллисекунды, если это необходимо: их указывают следующим параметром после секунд.
3. Вывод объекта календарь на экран
Если просто вывести объект-календарь на экран, результат вас не сильно порадует.
| Код |
|---|
|
| Вывод на экран |
|
Все дело в том, что календарь — это именно календарь, а не дата: у него много всяких настроек, и они все выводятся на экран.
Правильно будет отображать объект календарь с помощью класса SimpleDateFormat, но пока мы его не изучили, можно использовать лайфхак.
Date date = calendar.getTime();
Дело в том, что объект типа Calendar можно легко преобразовать к объекту типа Date, а как выводить на экран объект типа Date, вы уже знаете. Примерно так можно преобразовать объект Calendar в Date:
Использование метода getTime():
| Код | Вывод на экран |
|---|---|
|
|
Совсем другое дело, не так ли?
4. Работа с фрагментами даты
Чтобы получить фрагмент даты (год, месяц, ...), у класса Calendar есть специальный метод — get(). Метод один, зато с параметрами:
int month = calendar.get(Calendar.MONTH);
Где calendar — это переменная типа Calendar, а MONTH — это переменная-константа класса Calendar.
В метод get в качестве параметра вы передаете специальную константу класса Calendar, и в результате получаете нужное значение.
Примеры
| Код | Описание |
|---|---|
|
эра (до нашей эры или после) год месяц день месяца день недели часы минуты секунды |
Для изменения фрагмента даты используется метод set:
calendar.set(Calendar.MONTH, значение);
Где calendar — это переменная типа Calendar, а MONTH — это переменная-константа класса Calendar.
В метод set в качестве первого параметра вы передаете специальную константу класса Calendar, а в качестве второго параметра — новое значение.
Примеры
| Код | Описание |
|---|---|
|
год = 2019 месяц = Июль (нумерация с 0) 4 число часы минуты секунды |
5. Константы класса Calendar
В классе Calendar есть константы не только для названия фрагментов даты, а кажется, на все случаи жизни.
Calendar date = new GregorianCalendar(2019, Calendar.JANUARY, 31);
Например, есть константы для обозначения месяцев:
Или, например, для дней недели:
Calendar calendar = new GregorianCalendar(2019, Calendar.JANUARY, 31);
if (calendar.get(Calendar.DAY_OF_WEEK) == Calendar.FRIDAY)
{
System.out.println("Это пятница");
}
Всего перечислять не будем. Просто хотим, чтобы вы не удивлялись, если встретите такие записи в коде.
Использование констант позволяет сделать код более читабельным, поэтому программисты их и добавили. Ну а месяцы нумеруются с нуля тоже ради читабельности. Или нет.
6. Изменение даты в объекте Calendar
У класса Calendar есть метод, который позволяет проводить с датой более умные операции. Например, добавить к дате год, месяц или несколько дней. Или отнять. Называется этот метод add(). Выглядит работа с ним примерно так:
calendar.add(Calendar.MONTH, значение);
Где calendar — это переменная типа Calendar, а MONTH — это переменная-константа класса Calendar.
В метод add в качестве первого параметра вы передаете специальную константу класса Calendar, и в качестве второго параметра — значение, которое нужно добавить.
Особенность этого метода в том, что он умный. Давайте сами посмотрим, насколько:
| Код |
|---|
|
| Вывод на экран |
|
Этот метод понимает, что в феврале 2019 года всего 28 дней, и итоговая дата — 1 марта.
А теперь давайте отнимем 2 месяца! Что должно получиться? 27 декабря 2018 года! Сейчас проверим.
Чтобы выполнить действие, уменьшающее дату, нужно в метод add() передать значение с отрицательным знаком:
| Код |
|---|
|
| Вывод на экран |
|
Работает!
Этот метод учитывает длины месяцев и високосные годы. В общем, отличный метод. Именно то, что нужно большинству программистов, которые плотно работают с датами.
7. Прокручивание фрагментов даты
Но иногда бывают ситуации, когда такое умное поведение излишне: хочется что-то сделать с одной частью даты, не меняя все остальное.
Для этого у класса Calendar есть специальный метод — roll(). По своей сигнатуре он полностью аналогичен методу add(), но любые изменения с его помощью затрагивают один параметр, остальные остаются неизменными.
Пример:
| Код |
|---|
|
| Вывод на экран |
|
Месяц мы поменяли, а год и число остались неизменными.
ПЕРЕЙДИТЕ В ПОЛНУЮ ВЕРСИЮ
Или нет. Я бы написал "Но это не точно" 😀