Статьи

Как форматировать / анализировать даты с LocalDateTime в Java 8 — Пример учебника

Одной из распространенных задач в Java-проекте является форматирование или разбор даты в String и наоборот. Дата анализа означает, что у вас есть строка, представляющая дату, например «2017-08-3», и вы хотите преобразовать ее в объект, представляющий дату в Java, например, java.util.Date в мире до Java 8 и LocalDate или LocalDatetime в мире Java 8. Аналогично, форматирование даты означает преобразование экземпляра даты в строку, например, у вас есть объект Date или объект LocalDatetime, и вы хотите получить строку в формате dd-MM-yyyy.

Java 8 API обеспечивает хорошую поддержку форматирования и разбора дат. Например, если у вас есть дата в виде строки, например «2017-08-3 12:30», и вы хотите преобразовать ее в экземпляр LocalDateTime, который является новым классом из API даты и времени JDK 8 и содержит дату и время часть, как ты это делаешь? Ну, для этого вы можете использовать метод format () и parse () из класса LocalDateTime, но вам нужна еще одна вещь, формат даты.

До Java 8 вы могли знать, что мы используем классы SimpleDateFormat и DateFormat для представления формата, который имеет много проблем, например, они были тяжелыми, изменяемыми и не поточнобезопасными, что означает, что вы не можете делиться ими и каждый раз, когда вам нужно Чтобы преобразовать String в Date, вы должны создать новый объект DateFormat. Хотя инкапсуляция SimpleDateFormat в локальную переменную потока дает некоторую передышку, этого было недостаточно.

JDK 8 решил эту проблему в новом классе DateTimeFormatter, который можно использовать для определения формата даты и времени, например, «гггг-мм-дд ЧЧ: мм», синтаксис для указания формата такой же, как мы использовали ранее в классе SimpleDateFormat , но этот класс является как потокобезопасным, так и неизменным, что означает, что вы можете разделить его экземпляр между потоками В идеале вы можете сохранить ссылку DateTimeFormatter в статическую переменную, чтобы сделать ее глобальной.

Другое преимущество использования DateTimeFormatter состоит в том, что он предлагает несколько встроенных средств форматирования, например, java.time.format.DateTimeFormatter.ISO_LOCAL_DATE_TIME, которые могут представлять дату как
«2017-08-03T10: 15: 30». Вы можете увидеть полный список встроенных средств форматирования в Javadoc или вы можете прочитать Java SE 8 для Really Impatient, чтобы узнать больше об этом.

После того, как вы получили свой форматтер, анализировать или форматировать дату так же просто, как вызывать метод. Вам просто нужно вызвать метод LocalDateTime.parse () для преобразования String в LocalDateTime в Java 8. Parse () принимает String и анализирует в экземпляр LocalDateTime на основе формата, указанного в DateTimeFormatter. Метод parse () также перегружен, и по умолчанию он использует формат ISO_LOCAL_DATE_TIME, который имеет формат «гггг-мм-дд ЧЧ: мм», то есть «2017-08-03T10: 15: 30», но если ваша строка имеет другой формат, то Вы можете указать отдельный форматер.

Итак, достаточно теории, давайте начнем настоящую работу …

Как форматировать даты с LocalDateTime

Предположим, вы загружаете дату в виде строки из базы данных или файла в формате ISO, например «гггг-мм-дд ЧЧ: мм», и хотите преобразовать их в java.time.LocalDateTime. Вот точные шаги для анализа строки даты в LocalDateTime в Java 8:

1) Создайте объект DateTimeFormatter

2) Используйте метод LocalDateTime.parse (string, formatter) для преобразования объекта String в объект LocalDatetime

Кстати, в нашем случае даты имеют формат ISO, вам не нужно создавать отдельный форматер, и вы можете напрямую вызвать метод синтаксического анализа, как показано в следующем примере:

1
2
3
4
5
6
7
8
9
String date = "2017-03-08T12:30:54";
LocalDateTime localdatetime = LocalDateTime.parse(date);
 
System.out.println("origional date as string: " + date);
System.out.println("generated LocalDateTime: " + localdatetime);
 
Output
origional date as string: 2017-03-08T12:30:54
generated LocalDateTime: 2017-03-08T12:30:54

Кстати, если ваша строка даты не в формате ISO, ожидаемом методом разбора, например, нет T или пропущенной минуты второй части, то она выдаст исключение DateTimeParseException. Например, если вы хотите проанализировать «2017-08-3 12:30» или «2017-03-08 12:30:54», будет выдано следующее исключение:

Исключение в потоке «main» java.time.format.DateTimeParseException: текст «2017-03-08T12: 30: 54» не может быть проанализирован по индексу 10 в java.time.format.DateTimeFormatter.parseResolved0 (DateTimeFormatter.java:1949) в java.time.format.DateTimeFormatter.parse (DateTimeFormatter.java:1851) в java.time.LocalDateTime.parse (LocalDateTime.java:492) в Demo.main (Demo.java:22)

Чтобы избежать этой ошибки, вы можете создать экземпляр DateTimeFormatter, который соответствует вашей строке даты. Например, если ваши даты похожи на «2017-08-3 12:30», вы можете создать DateTimeFormatter, как показано ниже:

1
DateTimeFormatter format = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm");

После этого вы можете использовать этот экземпляр форматера для анализа String в LocalDateTime, как показано в следующем примере:

01
02
03
04
05
06
07
08
09
10
String date = "2017-03-08 12:30:54";
DateTimeFormatter format = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm");
LocalDateTime dateTime = LocalDateTime.parse(date, format);
 
System.out.println("origional date as string: " + date);
System.out.println("generated LocalDateTime: " + dateTime);
 
Output:
origional date as string: 2017-03-08 12:30
generated LocalDateTime: 2017-03-08T12:30

Вы можете видеть, что больше нет исключений, но вы должны убедиться, что дата, так как String должна соответствовать шаблону, который вы определили в своем экземпляре DateTimeFormatter. Поскольку он также является поточно-ориентированным и неизменным, вы можете даже хранить его в статической переменной и обмениваться ею с другими частями вашей программы. Подробнее о безопасности потоков и неизменяемости вы можете узнать в новом API даты и времени на
Java SE 8 для действительно нетерпеливой книги.

Как форматировать даты с LocalDateTime

В последнем разделе вы узнали, как анализировать дату, например, преобразовать строковое представление даты в соответствующий объект, то есть LocalDateTime в Java 8. Теперь давайте сделаем обратное, создадим отформатированную строку из существующего объекта LocalDateTime, например, даты в формате «дд-мм-гггг».

Опять же нам нужен экземпляр DateTimeFormatter, который содержит наш шаблон даты, а затем мы можем использовать метод format () класса LocalDateTime для достижения этой цели. Однако вы должны помнить, что format () является нестатическим методом, и вам нужен экземпляр класса LocalDateTime для вызова этого метода. Вот пример для форматирования дат с помощью LocalDatetime в Java 8:

01
02
03
04
05
06
07
08
09
10
DateTimeFormatter aFormatter = DateTimeFormatter.ofPattern("dd-MM-yyyy HH:mm");
LocalDateTime localDateTime = LocalDateTime.of(2017, Month.AUGUST, 3, 12, 30);
String foramttedString = localDateTime.format(aFormatter); // "2017-03-08 12:30"
 
System.out.println("origional LocalDatetime object: " + localDateTime);
System.out.println("generated string : " + foramttedString);
 
Output:
origional LocalDatetime object: 2017-08-03T12:30
generated string : 03-08-2017 12:30

Вы должны заметить, что мы вызываем метод форматирования объекта, а не класса, потому что это нестатический метод, который противоположен parse (), который является статическим методом. Вы также можете видеть, что сгенерированная строка подтверждает ваш паттерн, т.е. «03-08-2017 12:30» в формате «дд-мм-гггг ЧЧ: мм».

Java программа для форматирования / анализа даты с LocalDateTime в JDK 8

Это наш пример Java-программы, которая инкапсулирует примеры разбора и форматирования дат с помощью LocalDateTime в Java 8.

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
import java.time.LocalDateTime;
import java.time.Month;
import java.time.format.DateTimeFormatter;
 
/*
* Java Program to parse to LocalDateTime in JDK 8.
* We'll convert a String "2017-03-08 12:30" into LocalDateTime.
* we'll also see how to format a LocalDateTime instance to String format.
*/
public class Demo {
 
public static void main(String[] args) throws Exception {
 
// parsing a string date to LocalDateTime
String date = "2017-03-08 12:30";
DateTimeFormatter format = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm");
LocalDateTime dateTime = LocalDateTime.parse(date, format);
 
System.out.println("origional date as string: " + date);
System.out.println("generated LocalDateTime: " + dateTime);
 
 
//formatting a LocalDateTime to string instance
DateTimeFormatter aFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm");
LocalDateTime localDateTime = LocalDateTime.of(2017, Month.AUGUST, 3, 12, 30);
String foramttedString = localDateTime.format(aFormatter); // "2017-03-08 12:30"
 
System.out.println("origional LocalDatetime object: " + localDateTime);
System.out.println("generated string : " + foramttedString);
 
// be careful, string must contain date and time portion
// if you are converting to LocalDateTime, or else, your
// code will break
 
LocalDateTime dateWithoutTime = LocalDateTime.parse("2017-08-03", format);
}
 
}
 
Output
origional date as string: 2017-03-08 12:30
generated LocalDateTime: 2017-03-08T12:30
origional LocalDatetime object: 2017-08-03T12:30
generated string : 2017-08-03 12:30
Exception in thread "main" java.time.format.DateTimeParseException:
Text '2017-08-03' could not be parsed at index 10
at java.time.format.DateTimeFormatter.parseResolved0(DateTimeFormatter.java:1949)
at java.time.format.DateTimeFormatter.parse(DateTimeFormatter.java:1851)
at java.time.LocalDateTime.parse(LocalDateTime.java:492)
at Demo.main(Demo.java:35)

Важные точки

1) Метод LocalDateTime.parse () используется для анализа и является статическим методом, но метод format () не является статическим, и для его вызова требуется экземпляр LocalDateTime. Это важное различие между parse () и format (). Например, LocalDateTime.format (DateTimeFromatter) недопустим в Java и выдает ошибку времени компиляции.

2) Вы должны убедиться, что ваша String подтверждает формат, который вы используете как для синтаксического анализа, так и для форматирования, если это не так, тогда оба метода parse () и format () генерируют исключение DateTimeParseException, например, «Exception in thread« main »java.time. .format.DateTimeParseException: текст ‘2017-08-03’ не может быть проанализирован с индексом 10 ″.

3) Существует несколько встроенных форматов, доступных в Java 8, и мы должны использовать их, если цель разделяется, а не создается новый.

4) Поскольку DateTimeFormatter является как неизменяемым, так и поточно-ориентированным, рекомендуется хранить его в статической переменной и делить его с кем угодно, но убедитесь, что переменная является как статической, так и конечной, чтобы поток мог ее прочитать, но не смог назначить новый ссылка или ноль к нему, что может вызвать тонкие проблемы. См. Мой пост об опасностях использования статической переменной в многопоточной среде для более подробной информации.

Вот сводка кода для форматирования или анализа даты в LocalDateTime в Java 8:

Это все о том, как форматировать и анализировать даты с помощью LocalDateTime в Java 8 . Как я уже сказал, каждый новый класс, например LocalDate, LocalTime и LocalDateTime, имеет метод синтаксического анализа и форматирования, который можно использовать для преобразования строки в дату и наоборот. Просто помните, что вам нужен DateTimeFormatter, чей шаблон должен совпадать с вашей строкой даты, если это не так, то оба метода parse () вызовут ошибку java.time.format.DateTimeParseException.

Вы также должны помнить разницу между методами parse () и format (), прежний является статическим, а позже нестатическим. Еще одна вещь, которую вы должны иметь в виду, это повторно использовать экземпляр DateTimeFormatter либо в форме статической переменной, либо используя несколько встроенных средств форматирования, доступных в JDK. Вы также можете прочитать Java SE 8 for Really Impatient, чтобы узнать больше о новых функциях Java 8, в том числе о новом API даты и времени.

Другой учебник по дате и времени Java 8, который вы можете изучить:

Как сравнить две даты в Java? ( учебник )
Как получить текущее значение метки времени в Java? ( учебник )
Как преобразовать строку в LocalDateTime в Java 8? ( пример )
Как преобразовать java.util.Date в java.sql.Timestamp в JDBC? ( учебник )
Как преобразовать Дата в LocalDateTime в Java 8? ( учебник )
Как узнать текущую дату и время в Java 6? ( учебник )
Как разобрать строку в дату с помощью библиотеки JodaTime? ( пример )
Как преобразовать java.util.Date в java.sql.Date в JDBC? ( учебник )
Как преобразовать String в LocalDateTime в Java 8 ( учебник )

Спасибо за чтение этой статьи до сих пор. Если вам нравится этот учебник по дате и времени Java 8 и мои советы, поделитесь с друзьями и коллегами. Если у вас есть какие-либо вопросы или пожелания, оставьте комментарий.