1. Класс Date и Unix-время

С самого появления языка Java в нем был специальный класс для работы со временем и датой — Date. С течением времени появилось еще несколько классов для работы с датой, но класс Date продолжает использоваться программистами до сих пор.

Все дело в том, что он очень простой и удобный. И вы как программист обязательно столкнетесь c ним в любом реальном проекте. Использовать его или нет — выбор за вами, но знать его вы обязаны. Поэтому уделите ему несколько минут вашего драгоценного времени.

Чем же так хорош класс Date? Своей простотой.

Класс Date хранит информацию о дате и времени в виде количества миллисекунд, прошедших с 1 января 1970 года. Это очень много миллисекунд, поэтому для их хранения используется тип long.

Интересно

Почему именно с 1970 года? Это так называемое Unix-time: именно так хранит время операционная система Unix, которая является бабушкой всех современных операционных систем.

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

Вот несколько полезных примеров работы с классом Date.


2. Получение текущей даты

Чтобы получить текущее время и дату, достаточно просто создать объект типа Date. Каждый новый объект хранит время (момент) его создания. Выглядит это очень просто:

Date current = new Date();

После выполнения этой команды переменная current будет хранить ссылку на созданный объект Date, который внутри себя будет хранить время его создания — количество миллисекунд, которое прошло с 1 января 1970 года.

Вывод текущей даты на экран

Чтобы вывести на экран текущую дату, просто: а) создайте новый объект Date, б) выведите его на экран с помощью метода System.out.println().

Пример:

Код Вывод на экран
Date current = new Date();
System.out.println(current);
Thu Feb 21 14:01:34 EET 2019

Вывод на экран расшифровывается так:

Текст Расшифровка
Thursday Четверг
February 21 21 Февраля
14:01:34 часы : минуты : секунды
EET Часовой пояс: East European Time (восточноевропейское время)
2019 Год

3. Задание определенной даты

Как получить текущее время мы разобрались, а как создать объект Date, который бы содержал другую дату или время?

Тут тоже все просто. Чтобы задать определенный день, нужно написать код вида:

Date birthday = new Date(год, месяц, день);

Все просто и очевидно, но есть два нюанса:

  1. Год нужно задавать от 1900.
  2. Месяцы нумеруются с нуля.
Интересно

Это тоже наследие операционной системы Unix: там программисты обозначали год двумя цифрами. Вместо 1977 писали просто 77. Поэтому 77 станет правильным годом, если мы считаем от 1900 года.

Например, я родился 21 марта 1989 года. Март — третий месяц, значит мне нужно написать

Код Вывод на экран
Date current = new Date(89, 2, 21);
System.out.println(current);
Tue Mar 21 00:00:00 EET 1989

Месяцы нумеруются с нуля, а дни — нет. Немного странно, да?

Думаем, настоящие программисты должны были пересилить себя и дни месяца тоже нумеровать с нуля. Ох уж эти конформисты 🙂

Задание определенного времени

Задать определенное время тоже достаточно просто: для этого нужно написать команду вида:

Date birthday = new Date(год, месяц, день, час, минуты, секунды);

Часы, минуты и секунды нумеруются с нуля: программист внутри вас должен вздохнуть спокойно.

Пример:

Код Вывод на экран
Date current = new Date(105, 5, 4, 12, 15, 0);
System.out.println(current);
Sat Jun 04 12:15:00 EEST 2005

Мы задали время 12:15 и дату 4 июня 2005 года. Читается немного сложновато для не программиста, зато работает как надо.


4. Работа с фрагментами даты

Объект Date можно не просто выводить на экран. У него есть методы, которые позволяют получить отдельные фрагменты его даты:

Метод Описание
int getYear()
Возвращает год даты относительно 1900 года.
int getMonth()
Возвращает месяц даты, месяцы нумеруются с нуля
int getDate()
Возвращает день месяца
int getDay()
Возвращает день недели
int getHours()
Возвращает часы
int getMinutes()
Возвращает минуты
int getSeconds()
Возвращает секунды

Пример:

Код Вывод на экран Примечание
Date current = new Date(105, 5, 4, 12, 15, 0);
System.out.println(current.getYear());
System.out.println(current.getMonth());
System.out.println(current.getDate());
System.out.println(current.getDay());

105
5
4
6

2005 год
июнь
день месяца
суббота

Кстати, у объекта Date отдельные фрагменты даты можно не только получать, но и изменять:

Метод Описание
void setYear(int year) Меняет год даты. Год задаётся относительно 1900 года.
void setMonth(int month) Меняет месяц даты, месяцы нумеруются с нуля
void setDate(int date) Меняет день месяца
void setHours(int hours) Меняет часы
void setMinutes(int minutes) Меняет минуты
void setSeconds(int seconds) Меняет секунды

5. Миллисекунды

Как мы уже говорили, внутри объекта Date хранится количество миллисекунд, прошедшее с 1 января 1970 года.

Если оно нам нужно, мы можем получить его у объекта Date:

long time = date.getTime();

Метод getTime() возвращает количество миллисекунд, которое хранится внутри объекта Date.

Вы можете не просто получить количество миллисекунд, но и изменить его в существующем объекте:

Date date = new Date();
date.setTime(1117876500000L);

Кстати, можно записать эту конструкцию короче, передав время в объект Date прямо во время его создания:

Date date = new Date(1117876500000L);

6. Сравнение дат

Если вы хотите сравнить две даты и узнать, какая из них была раньше, для этого есть три способа

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

if (date1.getTime() < date2.getTime())

Способ второй — использовать метод before() объекта Date:

if (date1.before(date2))

Читается это так: если date1 перед date2, то...

Способ третий — использовать метод after() объекта Date:

if (date2.after(date1))

Читается это так: если date2 после date1, то...


7. Класс DateFormat

Помните, когда мы выводили дату на экран, отображалось что-то типа Thu Feb 21 14:01:34 EET 2019. Вроде бы все правильно, но это скорее отображение даты для программиста. А для пользователя хотелось бы отображать дату попонятнее. Что-нибудь типа Вторник, 21 Февраля.

И без года. Ну или с годом, если надо. В общем, хотелось бы отображать дату разными способами.

Для этого есть специальный класс — SimpleDateFormat.

Пример:

Код
Date current = new Date(105, 5, 4, 12, 15, 0);
SimpleDateFormat formatter = new SimpleDateFormat("MMM-dd-YYYY");
String message = formatter.format(current);
System.out.println(message);
Вывод на экран
Jun-04-2005

Видите, что программа вывела на экран: Jun-04-2005. Совсем не то, что раньше.

А все дело в том, что мы отображали не сам объект Date, а специальную строку, полученную вызовом метода format() у объекта типа SimpleDateFormat. Но ключевое здесь даже не это.

Когда объект SimpleDateFormat создается, в него в виде параметров мы передаем строку "MMM-dd-YYYY". Вот в этой строке и зашифрован формат даты, который вы увидели в итоге на экране.

  • MMM значит вывести название месяца, сокращенное до трех букв
  • dd — вывести день месяца
  • YYYY — вывести год, состоящий из четырех цифр

Если мы хотим вывести месяц в виде цифр, нужно вместо MMM написать MM: получится строка "MM-dd-YYYY". На экран будет выведено 06-04-2005

Более детально мы разберём этот класс позднее.


8. Метод Date.parse

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

Для этого у него есть специальный метод — parse(). Выглядит процесс парсинга так:

Date date = new Date();
date.setTime( Date.parse("Jul 06 12:15:00 2019") );

Кстати, этот же код можно записать более компактно:

Date date = new Date("Jul 06 12:15:00 2019");

Более подробно парсинг строк мы разберем в других лекциях.


undefined
17
Задача
Java Syntax Pro, 17 уровень, 2 лекция
Недоступна
Лишь бы не в понедельник :)
Проинициализируй переменную birthDate объектом Date с датой своего рождения. Реализуй метод getDayOfWeek(Date date), чтобы он возвращал русское название дня недели аргумента date.
undefined
17
Задача
Java Syntax Pro, 17 уровень, 2 лекция
Недоступна
Подчищаем хвосты
Метод fixDate принимает в качестве параметра список дат. Некоторые из них содержат две типичные ошибки: неправильно сохраняются (и, следовательно, выводятся в консоли) год и месяц. То есть, неправильная дата содержит всегда две ошибки (год и месяц), которые тебе нужно исправить в методе fixDate,
undefined
17
Задача
Java Syntax Pro, 17 уровень, 2 лекция
Недоступна
Чиним формат
Исправь ошибку, чтобы программа вывела "2010-01-06". Инициализацию переменной date не меняй.