Преобразование строки в дату на Java (или на любом другом языке
программирования) - это фундаментальный навык, который полезно знать при
работе над проектами. Иногда проще работать со строкой, представляющей
дату, а затем преобразовать ее в Date
для дальнейшего использования.
В этой статье мы рассмотрим множество методов и библиотек, которые вы можете использовать для преобразования строки Java в объект даты.
API даты / времени
API даты / времени в Java по умолчанию работает с форматом ISO
8601 (yyyy-MM-dd)
.
Все даты по умолчанию следуют этому формату, и все преобразованные строки должны следовать ему, если вы используете средство форматирования по умолчанию.
анализировать ()
Этот API определяет parse()
который принимает последовательность
символов и использует ISO_LOCAL_DATE
для анализа ввода:
parse(CharSequence);
В качестве альтернативы вы можете использовать вариант этого метода с двумя аргументами, определяя другой модуль форматирования:
parse(CharSequence, DateTimeFormatter);
DateTimeFormatter
используется для форматирования и анализа объектов
даты и времени в новом API даты и времени. Все классы даты и времени из
этого API содержат метод синтаксического анализа и форматирования,
каждый из которых принимает DateTimeFormatter для определения шаблона.
Преобразование строки в LocalDate
LocalDate
представляет дату без времени в формате ISO-8601.
Он отличается от Date
тем, что хранит время не в виде миллисекундного
смещения с начала эпохи, а просто текущую дату. Это также более новая
реализация API даты / времени и предлагает собственный метод
форматирования / анализа, а также добавление и вычитание дней, недель и
лет, чего нет в варианте Date.
Чтобы преобразовать строку в LocalDate
, достаточно написать:
LocalDate date = LocalDate.parse("2018-09-16");
LocalDate
кода для создания экземпляра объекта LocalDate:
LocalDate date = LocalDate.of(2018, 09, 16);
Преобразование строки в LocalTime
LocalTime
представляет время без часового пояса в формате ISO-8601. Он
не хранит время на основе смещения с эпохи и обеспечивает точность в
наносекунду.
Как и LocalDate, он предоставляет множество очень полезных встроенных методов синтаксического анализа и форматирования, а также средства для добавления или вычитания из него времени.
Чтобы преобразовать строку в LocalTime
, достаточно написать:
LocalTime localTime = LocalTime.parse("8:00");
LocalTime
кода для создания экземпляра объекта LocalTime:
LocalTime localTime = LocalTime.of(8, 00);
Преобразование строки в LocalDateTime
LocalDateTime
- это наиболее часто используемый класс для даты и
времени в Java. Он представляет собой комбинацию даты и времени и может
использоваться для многих целей:
LocalDateTime localDateTime = LocalDateTime.parse("2018-09-16T08:00:00");
Сначала этот формат может показаться запутанным, но на самом деле он довольно прост:
{.ezlazyload .img-responsive}
Маркер «Время» просто представляет собой линию между частями формата
LocalDate
и LocalTime
Вы также можете легко отформатировать этот LocalDateTime
в более
читаемый формат:
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
String formatDateTime = localDateTime.format(formatter);
Запуск этого фрагмента кода и печать formatDateTime
даст:
2018-09-16 08:00:00
Обычно вы делаете это, чтобы показать результат конечному пользователю в
строковом формате, предварительно LocalDateTime
Преобразование строки в ZonedDateTime
В зависимости от проекта, над которым вы работаете, вам может потребоваться обрабатывать разные часовые пояса при работе с датами и временем.
Преобразование String в ZonedDateTime
так же просто, как:
ZonedDateTime zonedDateTime = ZonedDateTime.parse("2018-09-16T08:00:00+00:00[Europe/London]");
В приведенном выше примере показано, как инициализировать
ZonedDateTime
для Лондона.
Преобразование строки с помощью специального средства форматирования
Иногда мы могли бы пожелать использовать наш собственный модуль
форматирования, который принимает строку самыми разными способами и при
этом не генерирует DateTimeParseException
.
Вот некоторые из наиболее распространенных шаблонов, которые вы бы использовали:
y
: Год (2018, 18)M
: Месяц в году (август, август 08)d
: День в месяце (1, 5, 25)E
: Название дня недели (понедельник, суббота)a
: маркер Ante meridiem / Post meridiem (AM, PM)H
: Час в 24-часовом стиле (1, 7, 14, 21)h
: Час в 12-часовом стиле (1, 5, 12)m
: Минута в часе (1, 25, 54)s
: Секунда в минуту (1, 25, 54)
И некоторые из них, возможно, вы не используете так часто:
G
: обозначение эпохи (AD, CE)Y
: год недели (2018, 18)w
: Неделя в году (25, 53)W
: Неделя в месяц (2)D
: День в году (254)F
: День недели в месяце (3)E
: название дня недели (понедельник, понедельник)u
: номер дня недели (1, 4)k
: Час в день (17)K
: Час в день в AM / PM (5)S
: Миллисекунда (1245)z
: Общий часовой пояс (стандартное тихоокеанское время; PST; GMT-8: 00)Z
: RFC 822 Часовой пояс (-0800)X
: Часовой пояс ISO 8601 (-08, -0800, -8: 00)
Примечание. Год недели отличается от года - год недели
синхронизируется с циклом WEEK_OF_YEAR
Все недели между первой и
последней неделями (включительно) имеют одинаковое значение года недели.
Следовательно, первый и последний дни недели могут иметь разные значения
календарного года.
Примечание: K
и H
различаются так же, как различаются k
и h
H
и h
относятся к моделям 0-23 и 1-12 соответственно, а K
и k
относятся к моделям 0-11 и 1-24 соответственно.
Если это по-прежнему не удовлетворяет вашу потребность в настраиваемом средстве форматирования, вы можете использовать DateTimeFormatterBuilder для создания очень конкретных и сложных средств форматирования. Среди прочего, DateTimeFormatter построен с использованием этого класса.
java.util.Date
Это более старый подход, который сегодня нечасто используется, но его все же стоит рассмотреть, поскольку иногда мы все еще используем классы из этих API:
SimpleDateFormat formatter = new SimpleDateFormat("dd-MM-yyyy");
Date date = formatter.parse("22-Sep-2018");
Есть много шаблонов, которые мы можем передать в конструктор
SimpleDateFormat
. Вы можете комбинировать практически любое
количество форматов, используя доступные шаблоны.
Установить часовой пояс для Date невозможно, потому что он просто не содержит такой информации. Однако легко отформатировать дату и добавить информацию о часовом поясе в строку:
SimpleDateFormat formatter = new SimpleDateFormat("dd-M-yyyy hh:mm:ss a");
formatter.setTimeZone(TimeZone.getTimeZone("UTC"));
Date date = formatter.parse("22-09-2018 08:23:43 PM");
String formattedDate = formatter.format(date);
System.out.println(date);
System.out.println(formattedDate);
Выполнение этого фрагмента кода даст:
Sat Sep 22 22:23:43 CEST 2018
22-9-2018 08:23:43 PM
«22:23:43 CEST» соответствует времени «10:23:43 PM», а форматированная дата представляет «8:23:43 PM», поскольку находится в другом часовом поясе.
SimpleDateFormat против DateTimeFormatter
Читая эту статью, уместно задать вопрос - «В чем разница, и какой из них я должен использовать? »
DateTimeFormatter
был добавлен в Java 8 с новым API даты / времени и
заменяет старый, теперь реже используемый SimpleDateFormat
. Он
поточно-ориентирован, в отличие от своего старого аналога, и предлагает
новые функции:
// SimpleDateFormat
SimpleDateFormat formatter = new SimpleDateFormat("dd-M-yyyy");
Date date = new Date();
String formattedDate = formatter.format(date);
Date parsedDate = formatter.parse(formattedDate);
// DateTimeFormatter
LocalDate date = LocalDate.now();
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("dd-M-yyyy");
String formattedDate = date.format(formatter);
LocalDate parsedDate = LocalDate.parse(formattedDate, formatter);
Ясно видеть разницу между этими двумя. Раньше средство форматирования
использовалось для форматирования, а затем для анализа даты. В более
новом способе даты имеют собственный формат и методы синтаксического
анализа, а DateTimeFormatter
просто для шаблона.
Если вы используете Java 8 и новый API, используйте DateTimeFormatter, а если вы все еще используете старую версию Java, используйте SimpleDateFormat.
Джода-Тайм
Joda-Time был разработан для решения проблем со старыми классами времени и даты Java.
Начиная с Java 8, эти проблемы были исправлены, и Joda-Time выполнила
свою задачу. Даже его авторы советуют перейти на официальный java.time
для работы с датой и временем.
В том случае, если это невозможно и для тех, кто все еще использует версию Java до Java 8, Joda-Time по-прежнему остается отличной библиотекой.
Зависимость для этой библиотеки можно легко добавить с помощью зависимости Maven:
<dependency>
<groupId>joda-time</groupId>
<artifactId>joda-time</artifactId>
<version>{version}</version>
</dependency>
Работа с Joda-Time очень похожа на работу с Java Date / Time API:
DateTimeFormatter formatter = DateTimeFormatter.forPattern("dd-MM-yyyy HH:mm:ss");
DateTime dateTime = DateTime.parse("22-Sep-2018 8:15:43", formatter);
DateTime
Joda-Time также поддерживает часовые пояса:
DateTimeFormatter formatter = DateTimeFormatter.forPattern("dd-MM-yyyy HH:mm:ss");
DateTime dateTime = DateTime.parse("22-Sep-2018 8:15:43", formatter);
DateTime dateTimeZoned = dateTime.withZone(DateTimeZone.forID("Europe/London));
Полный список доступных для использования идентификаторов часовых поясов можно найти в официальной документации .
Apache Commons
Apache Commons - полезная библиотека, используемая во многих проектах.
Чтобы добавить эту библиотеку в свой проект, вы можете использовать зависимость Maven:
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-lang3</artifactId>
<version>{version}</version>
</dependency>
Обе реализации ниже принимают массив шаблонов. Эти методы будут
анализировать каждый шаблон за другим. Если никакой шаблон не
соответствует входной строке, ParseException
.
Использование DateTimeConverter
DateTimeConverter dtc = new DateConverter();
dtc.setPatterns(new String[] { "yyyy-MM-dd", "yyyy-MM-dd hh:mm:ss" });
ConvertUtils.register(dtc, Date.class);
Использование DateUtils
Date date = DateUtils.parseDate("22-Sep-2018", String[] {"dd-MM-yyyy HH:mm:ss", "dd-MM-yyyy"});
Заключение
Мы рассмотрели несколько способов преобразования простой String в классы Date и Date-Time в Java. Некоторые из этих подходов используют сторонние библиотеки, которые у вас, возможно, уже есть в вашем проекте, а некоторые реализованы с использованием API-интерфейсов, предлагаемых Java.