Строка даты синтаксического анализа для некоторого объекта Java
Я работаю над проектом, который считывает файлы и обрабатывает данные. Там я должен работать с датами, например:
- 2012-01-10 23:13:26
- 13 января 2012 г.
Я нашел пакет Joda, любопытный пакет, но не знаю, насколько он самый легкий.
Мне удалось проанализировать первый пример объекта DateTime (Joda) reg-ex и String. (Ех: путем замены пространства на '-' и передачи его конструктору.
new DateTime("2012-01-10 23:13:26".replace(' ', '-'))
Я думаю, это сработало, но проблема связана со вторым форматом. Как я могу использовать такой ввод для извлечения объекта, предпочтительно объекта Joda. Я уверен, что могу написать функцию, чтобы изменить формат того, что поддерживает Joda, но задавался вопросом, есть ли какой-нибудь другой способ (даже некоторая родная библиотека Java).
Если есть что-то лучше, чем Джода, пожалуйста, сообщите мне об этом.
Спасибо.
Ответы
Ответ 1
Используя Joda-Time, посмотрите DateTimeFormat; он позволяет анализировать строки типа даты, которые вы упоминаете (и почти любые другие произвольные форматы). Если ваши потребности еще сложнее, попробуйте DateTimeFormatterBuilder.
Разбор # 1:
DateTimeFormatter f = DateTimeFormat.forPattern("yyyy-MM-dd HH:mm:ss");
DateTime dateTime = f.parseDateTime("2012-01-10 23:13:26");
Изменить: на самом деле LocalDateTime является более подходящим типом для даты и времени без часового пояса:
LocalDateTime dateTime = f.parseLocalDateTime("2012-01-10 23:13:26");
И для # 2:
DateTimeFormatter f = DateTimeFormat.forPattern("MMMM dd, yyyy");
LocalDate localDate = f.parseLocalDate("January 13, 2012");
И да, Joda-Time - это, безусловно, путь к тому, что касается даты и времени Java.:)
Как правило, все согласятся, Joda - исключительно удобная библиотека. Например, я никогда раньше не делал такого разговора с Джодой, но мне потребовалось всего несколько минут, чтобы понять это из API и написать его.
Обновление (2015)
Если вы находитесь на Java 8, в большинстве случаев вам следует просто использовать java.time
вместо Joda -Время. Он содержит почти все хорошие вещи - или их эквиваленты - от Джоды. Для тех, кто уже знаком с API Joda, Стивен Коулбурн Joda-Time для руководства по переносу java.time пригодится.
Ниже приведены версии java.time приведенных выше примеров.
Разбор # 1:
DateTimeFormatter f = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
LocalDateTime dateTime = LocalDateTime.from(f.parse("2012-01-10 23:13:26"));
Вы не можете разобрать это в ZonedDateTime или OffsetDateTime (которые являются аналогами Joda DateTime, используемыми в моем первоначальном ответе), но этот вид имеет смысл, потому что в анализируемой строке нет информации о часовом поясе.
Разбор # 2:
DateTimeFormatter f = DateTimeFormatter.ofPattern("MMMM dd, yyyy");
LocalDate localDate = LocalDate.from(f.parse("January 13, 2012"));
Здесь LocalDate является наиболее подходящим типом для разбора (точно так же, как с Joda-Time).
Ответ 2
SimpleDateFormat будет анализировать даты в объектах Java Date:
http://docs.oracle.com/javase/1.4.2/docs/api/java/text/SimpleDateFormat.html
SimpleDateFormat format1 = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss"); // first example
SimpleDateFormat format2 = new SimpleDateFormat("MMMMM dd,yyyy"); // second example
Date d1 = format1.parse( dateStr1 );
Date d2 = format2.parse( dateStr2 );
Ответ 3
Я бы предположил, что у Джоды есть что-то вроде Formatter, чтобы сделать это за вас. Я нашел это с быстрым поиском google: http://johannburkard.de/blog/programming/java/date-time-parsing-formatting-joda-time.html
DateTimeFormatter parser1 =
DateTimeFormat.forPattern("dd/MMM/yyyy:HH:mm:ss Z");
DateTimeFormatter parser2 =
DateTimeFormat.forPattern("yyyy-MM-dd HH:mm");
DateTime time = parser1.parseDateTime("<data>");
Синтаксис, используемый для оценки шаблонов, можно найти в ссылке X-Zero.
Ответ 4
JodaTime в значительной степени считается стандартом де-факто для обработки даты на Java - они работают над тем, чтобы добавить его в следующую версию библиотеки Java (хорошо, эффективно).
Для получения дат JodaTime из строк вам нужно будет изучить класс DateTimeFormat.
Ответ 5
Самый простой способ - правильно настроить SimpleDateFormat в соответствии с форматом, который вы ожидаете, и использовать его метод синтаксического анализа, чтобы дать вам объект Date
Ответ 6
TL;DR
LocalDateTime ldt = LocalDateTime.parse( "2012-01-10 23:13:26".replace( " " , "T" ) );
... и...
LocalDate localDate = LocalDate.parse ( "January 13, 2012" , DateTimeFormatter.ofLocalizedDate ( FormatStyle.LONG ).withLocale ( Locale.US ) );
Подробнее
Ответ Jonik в основном правилен, но упускает некоторые важные проблемы.
java.time
Если есть что-то лучше, чем Джода, пожалуйста, сообщите мне об этом.
Да, есть что-то лучшее, java.time framework. Команда Joda-Time советует перейти на java.time как своего преемника.
Структура java.time встроена в Java 8 и более поздних версий. Эти классы вытесняют старые неудобные классы времени, такие как java.util.Date
, .Calendar
и java.text.SimpleDateFormat
.
Чтобы узнать больше, см. Учебник Oracle. И поиск Qaru для многих примеров и объяснений.
Большая часть функциональных возможностей java.time портирована на Java 6 и 7 в ThreeTen-Backport и далее адаптирована для Android в ThreeTenABP.
Дата-время
Ваш первый ввод - это дата плюс время дня. Ему не хватает offset-from-UTC или часовой пояс info, поэтому мы анализируем его как объект LocalDateTime
. "Местное..." означает любую местность, не определенную местность. Таким образом, это не настоящий момент на временной шкале, а скорее приблизительное представление о моменте.
Чтобы проанализировать входную строку 2012-01-10 23:13:26
, мы можем заменить SPACE посередине на T
, чтобы соответствовать каноническому стилю ISO 8601 стандартный формат значений даты и времени.
В классах java.time по умолчанию используются форматы ISO 8601 при разборе и генерации текстовых представлений значений даты и времени. Поэтому нет необходимости определять шаблон синтаксического анализа.
String input = "2012-01-10 23:13:26".replace( " " , "T" );
LocalDateTime ldt = LocalDateTime.parse( input );
Если вы знаете предполагаемый часовой пояс из контекста этого значения, примените его, чтобы определить фактический момент на временной шкале.
ZoneId zoneId = ZoneId.of( "America/Montreal" );
ZonedDateTime zdt = ldt.atZone( zoneId );
Дамп для консоли.
System.out.println ( "input: " + input + " | zdt: " + zdt );
input: 2012-01-10T23: 13: 26 | zdt: 2012-01-10T23: 13: 26-05: 00 [Америка/Монреаль]
Дата-только
Второй из ваших входов - это значение только для даты без времени и без часового пояса. Для этого нам нужен класс LocalDate
.
Я признаю формат этого ввода как соответствующий языку (английскому) и культурным нормам Соединенных Штатов. Поэтому нет необходимости явно указывать шаблон форматирования. Мы можем просто попросить форматера, который знает, что формат США, указав Locale
. Мы указываем FormatStyle.LONG
в зависимости от длины этого формата.
String input = "January 13, 2012";
DateTimeFormatter formatter = DateTimeFormatter.ofLocalizedDate ( FormatStyle.LONG ).withLocale ( Locale.US );
LocalDate localDate = LocalDate.parse ( input , formatter );
Дамп для консоли.
System.out.println ( "input: " + input + " | localDate: " + localDate );
ввод: 13 января 2012 | localDate: 2012-01-13