Подтвердить что ты не робот

Строка даты синтаксического анализа для некоторого объекта 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).

Если есть что-то лучше, чем Джода, пожалуйста, сообщите мне об этом.

Спасибо.

4b9b3361

Ответ 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