From 07fe867b60ae184e547d5f3d6e382fececea956d Mon Sep 17 00:00:00 2001 From: egorzhurov Date: Sat, 11 May 2024 12:02:07 +0300 Subject: [PATCH] Move 34 article to markdown format --- .../java-core/034/Date and time in Java.md | 154 ++++++++++++++++++ 1 file changed, 154 insertions(+) create mode 100644 lessons/java-core/034/Date and time in Java.md diff --git a/lessons/java-core/034/Date and time in Java.md b/lessons/java-core/034/Date and time in Java.md new file mode 100644 index 0000000..bf7b2b3 --- /dev/null +++ b/lessons/java-core/034/Date and time in Java.md @@ -0,0 +1,154 @@ +# Работа с датами и временем + +Работая с различными типами данных, ранее мы не касались вопросов работы с датой и временем. Тем не менее, классы для +работы с ними – одни из наиболее используемых. В рамках этого урока мы рассмотрим как устаревшие, так и современные типы +данных, предназначенных для работы с датой и временем. + +## Date. Calendar + +До Java 8 единственными, не касаясь внешних библиотек, способами работы с датами и временем были классы **Date** (по +сути, оберткой над временем, прошедшем с начала **UNIX-эпохи** – _с 1 января 1970 года_) и **Calendar**. Оба класса +являются изменяемыми. + +Более подробно с этими классами, а также с **форматированием** строк для их представления в виде объектов указанных +классов предлагаю познакомиться в рамках +[статьи](https://javarush.com/groups/posts/1941-kak-ne-poterjatjhsja-vo-vremeni--datetime-i-calendar) + +Данные классы все еще можно встретить в старых проектах, поэтому считаю необходимым иметь хотя бы общее представление о +них и методах, которые они предоставляют. + +Сами классы не считаются официально устаревшими – не помечены как `@Deprecated`, однако все конструкторы `Date`, кроме +конструктора по умолчанию (формирует объект для текущих даты и времени) и принимающего время в миллисекундах – уже +устарели. + +## Пакет java.time + +В рамках Java 8 – очень крупного релиза, по сути, заложившего основу Java в том виде, в котором она известна сегодня, +добавились и новые механизмы для работы с датой и временем – пакет `java.time`. + +Он предоставляет достаточно разнообразные инструменты. Сразу отмечу характерную особенностью рассматриваемых классов – +они неизменяемые. + +Более близкое знакомство начнем с идеологического наследника класса `Date` – `Instant`. Он также хранит время, прошедшее +с начала UNIX-эпохи. Данный класс тяжело назвать популярным, но иногда с ним приходится сталкиваться. Он является +достаточно специфичным в плане работы – в отличии от классов, рассматриваемых ниже, `Instant` лишен части узких методов +по манипуляции со значением. Те же, что есть – являются более многословными, нежели у классов, рассматриваемых ниже. + +Другой относительно большой блок классов представлен ниже. Их отличительной особенностью является то, что они НЕ +работают с датой и временем относительно начала UNIX-эпохи. И именно с этими классами придется сталкиваться чаще всего: + +- `LocalDate`. Класс для работы с датами. В отличии от `Date` или `Instant`, хранит год, месяц и дату в отдельных + полях. Более подробно с методами можно ознакомиться в [статье](https://metanit.com/java/tutorial/12.3.php); +- `LocalTime`. Все тоже самое, только для времени. Отдельной статьи под методы этого класса у меня нет, но большинство + из них однотипны с методами `LocalDate`. Предлагаю ознакомиться с ними самостоятельно; +- `LocalDateTime`. Класс, объединяющий `LocalDate` и `LocalTime` (они представлены полями в этом классе). Имеет методы, + возвращающие объект даты или времени (`toLocalDate()` и `toLocalTime()` соответственно). Обратите внимание, + классы `LocalDate` и `LocalTime` (в меньшей степени) также имеют методы, возвращающие объект типа `LocalDateTime`. В + целом, данный класс наиболее популярен из всего пакета; +- `ZonedDateTime`. Содержит внутри себя поле типа `LocalDateTime`, а также несколько объектов, отвечающих за **timezone + ** – часовой пояс. Как правило, в рамках внутренней логики используются объекты `LocalDateTime`, но общение с внешними + интерфейсами (получение и отправка дат при взаимодействии с клиентской (браузерной) частью клиент-серверного + приложения, например) происходит с помощью `ZonedDateTime`. + +Также описанные классы имеют функционал (методы) для создания объектов из `Instant`. Как и `Instant` имеет методы +создания объектов на основании параметров, являющихся наследниками `Temporal` (сюда относятся и сам `Instant`, и все +описанные в данном подразделе классы). Таким образом реализуется совместимость использования двух подходов по работе с +датой и временем в рамках `java.time`. + +В данной статье нет описания методов классов из `java.time`, поскольку они являются достаточно предсказуемыми на +основании названия (в отличии от некоторых методов `String`, например). Однако я настоятельно рекомендую ознакомиться с +ними самостоятельно. Обратите внимание, что объекты описанных выше классов создаются через статические методы, а не +конструкторы. + +## Пакет java.time. DateTimeFormatter + +Класс `DateTimeFormatter` выполняет примерно те же функции в `java.time`, что и `SimpleDateFormat` для работы с `Date` +и `Calendar`. Способ описания шаблонов также является схожим с `SimpleDateFormat`. + +Для желающих ознакомиться подробнее, рекомендую обратиться к +[документации](https://docs.oracle.com/javase/8/docs/api/java/time/format/DateTimeFormatter.html) +(там содержится и таблица обозначений для описания паттернов в `DateTimeFormatter`): + +В рамках данного класса рекомендую ознакомиться с константами типа `DateTimeFormatter`, которые там представлены (в +документации выше есть примеры для них, обратите внимание), а также тремя методами: + +1. `static ofPattern()`. Является перегруженным для указания локали. Возвращает объект `DateTimeFormatter` на основании + строки-паттерна, переданной параметром. Таким параметром может быть, например, _"yyyy-MM-dd HH:mm:ss"_; +2. `format()`. Возвращает строку на основании переданной параметром реализации `TemporalAccessor` (предок + интерфейса `Temporal`, который реализуют все рассмотренные в предыдущем подразделе классы `java.time`). Таким + образом, из метода мы получим строковое отражение даты и/или времени в необходимом формате. +3. `parse()`. Является противоположностью `format()` и возвращает объекты даты и/или времени (или `Temporal`, или его + наследника, если использовать перегруженный парметризованный метод) на основании переданной строки. Пример такой + строки – _"2022-12-20 19:51:00"_. Чаще всего этот метод не вызывается явно, вместо него используются статические + методы `parse()` в классах, объекты которых нужно получить. Внутри этих _static_-методов и вызывается рассматриваемый + метод. + +## Вместо итога + +Рассмотренная сегодня тема является, безусловно, важной и нужной. При этом она крайне проста, за исключением, возможно, +работы с форматерами. Однако я рекомендую плотно ознакомиться с методами создания, изменения, сравнения объектов даты +и/или времени, по крайней мере в рамках класса `LocalDateTime` и его составляющих. Нужные методы или однотипны, или +одноименны в различных классах, достаточно просты в запоминании, но их незнание может привести к усложнению логики без +всякой необходимости. Также рекомендую запомнить, у каких классов объекты будут изменяемы, а у каких – нет. Это тоже +несложно, но сэкономит время на исправлении простых ошибок в логике. + +Безусловно, пакет `java.time` шире, чем классы, которые мы рассмотрели. Как минимум, мы не познакомились с +интерфейсом `TemporalAmount` и его наследниками (наиболее известные - `Duration` и `Period`). + +Это не связано со сложностью использования остальной функциональности, скорее с тем, что необходимость в использовании +нерассмотренной части пакета возникает крайне редко. Но прежде чем изобретать собственный велосипед - всегда стоит +сначала поискать готовое решение. Поэтому при возникновении нестандартных задач в рамках данной темы рекомендую +обратиться, в первую очередь, к документации по пакету. + +#### С теорией на сегодня все! + +![img.png](../../../commonmedia/defaultFooter.jpg) + +Переходим к практике. Не вижу особого смысла давать задачи на классы из `java.util`, поэтому задания направлены на +закрепление знаний о `java.time`. Но вы можете самостоятельно адаптировать задачи под использование `Date` и `Calendar`, +если считаете необходимым. Я не откажу в их проверке. + +## Задача 1: + +Реализуйте метод, возвращающий объект `LocalDateTime` на основании переданной строки. Пример входящей строки: +_20.12.2022 20:16:00_. + +## Задача 2: + +Реализуйте программу, выводящую в консоль сообщение, являются ли введенные с клавиатуры дата и время больше или меньше +текущего. Формат вводимых даты и времени рекомендую взять из _Задачи 1_. + +## Задача 3: + +Реализуйте программу, выводящую в консоль количество времени между двумя введенными с клавиатуры датами и временем в +секундах, минутах, часах, днях, месяцах и годах. + +Пример ввода: + +``` + 20.12.2022 20:16:00 + 28.06.1932 02:51:56 +``` + +Пример вывода: + +``` + Seconds: 2855323444 + Minutes: 47588724 + Hours: 793145 + Days: 33047 + Months: 1085 + Years: 90 + Summary: 90 years, 5 months, 22 days, 17 hours 24 minutes 4 seconds +``` + +Примечание: данная задача не предполагает реализацию через наследников интерфейса `TemporalAmount`. Однако вы можете +использовать их для альтернативного решения. + +> Если что-то непонятно или не получается – welcome в комменты к посту или в лс:) +> +> Канал: https://t.me/ViamSupervadetVadens +> +> Мой тг: https://t.me/ironicMotherfucker +> +> **Дорогу осилит идущий!** \ No newline at end of file