2015-02-05 7 views
1

Я пытаюсь преобразовать строку ISO 8601 в согласованный формат, чтобы можно было сортировать и искать с использованием простого лексикографического порядка.Преобразование ISO 8601 Дата в стандартный строковый формат

Моего приложение может получить дату/время, в любом из следующих форматов, например:

2015-02-05T02:05:17.000+00:00 
2015-02-05T02:05:17+00:00 
2015-02-05T02:05:17Z 

Все они представляют собой то же дату/время, и я хотел бы, чтобы преобразовать их все в каноническую форму хранения, говорят:

2015-02-05T02:05:17.000Z 

Моя первая мысль была просто разобрать их, используя технику из Converting ISO 8601-compliant String to java.util.Date, а затем преобразовать обратно в нужной строке, но это ломается при работе с менее точной даты/времени, например:

2015-02-05T02:05:17Z 
2015-02-05T02:05Z 
2015-02-05Z 
2015-02Z 
2015Z 

Неточность этих времен должна быть сохранена. Они не должны быть преобразованы в:

2015-02-05T00:00:00.000Z 

Я смотрел Java 8 и Joda время, но они, кажется, хотят, чтобы рассматривать все, как определенные моменты времени, и не могут моделировать неточность или частичные даты/раз.

UPDATE:

Использование Java 8, я могу сделать:

OffsetDateTime dateTime = OffsetDateTime.parse("2015-02-05T02:05:17+00:00"); 
System.out.println(dateTime.toString()); 

, который дает мне:

2015-02-05T02:05:17Z 

чего я хочу, но:

OffsetDateTime dateTime = OffsetDateTime.parse("2015-02-05T02:05:17.000+00:00"); 
System.out.println(dateTime.toString()); 

также дает мне:

2015-02-05T02:05:17Z 

Обратите внимание, что java выбрасывает миллисекундную точность. Указание 000 обрабатывается так же, как не указывая ничего, что не кажется совершенно правильным.

+0

'2015-02-05T02: 05: 17 + 0000' не является действительной датой ISO. –

+1

Википедия предполагает, что +0000 является допустимым смещением. У вас есть лучшая ссылка? –

+0

Я не думаю, что есть один объект, который может содержать дату с ограничениями, которые вы определили (то есть частичная точность). Поэтому лучше всего использовать свое собственное представление. – eckes

ответ

5

В Java 8, вы можете использовать LocalDate.parse() или LocalDateTime.parse() на String без предоставления его с шаблоном, если строка в ISO формате .

parse(), Получает экземпляр LOCALDATE из текстовой строки, такие как 2007-12-03. Строка должна представлять действительную дату и обрабатывается с использованием DateTimeFormatter.ISO_LOCAL_DATE.

и

DateTimeFormatter.ISO_LOCAL_DATE, Это возвращает неизменный форматера, способный форматирования и синтаксического анализа ИСО 8601

, например,

String strDate = "2015-08-04"; 
LocalDate aLD = LocalDate.parse(strDate); 
System.out.println("Date: " + aLD); 

String strDatewithTime = "2015-08-04T10:11:30"; 
LocalDateTime aLDT = LocalDateTime.parse(strDatewithTime); 
System.out.println("Date with Time: " + aLDT); 

дает,

Date: 2015-08-04 
Date with Time: 2015-08-04T10:11:30 

Update:

ваша дата, т.е. "2015-02-05T02:05:17.000+00:00" бы только выбросить нули прочь когда они все нули, если значение наносекунд является иным, чем нулей, то он будет отображаться нормально, однако, если вы хотите, чтобы отобразить нули тоже, то вы можете просто добавить if/else блок и добавлять нули к вашей дате if ваш нано-на-секунды нули (yourdate.getNano()==0) else печать это, как это,

String dateTimestr = "2015-02-05T02:05:17.000+00:00"; 

OffsetDateTime dateTime = OffsetDateTime.parse(dateTimestr); 

if ((dateTime.getNano() == 0) && (dateTimestr.length() > 25)) 
    System.out.println(dateTime.toLocalDateTime() + ".000Z"); 

else 
    System.out.println(dateTime.toString()); 

даст,

2015-02-05T02:05:17.000Z 

изменив дату,

String dateTimestr = "2015-02-05T02:05:17+00:00"; 

дает,

2015-02-05T02:05:17Z 

изменения даты,

String dateTimestr = "2015-02-05T02:05:17.100+00:00"; 

дает,

2015-02-05T02:05:17.100Z 

изменяя его,

String dateTimestr = "2015-02-05T02:05:17Z"; 

дает,

2015-02-05T02:05:17Z 
+0

Это очень полезно, но, пожалуйста, посмотрите мое обновление, почему оно не работает. –

+1

Непонятно, как это относится к проблеме поддержания точности (и отсутствия точности) –

+0

@JamesScriven, пожалуйста, прочитайте обновленный ответ. –

1

Вы должны понимать, что сохранение точности может происходить только в текстовом пространстве, но не в пространстве значений. Таким образом, различная степень точности может быть выражена текстовым способом (см. Ваш ввод), но не в объекте значения (здесь тип OffsetDateTime). В Latter хранится только дата-значение, но не дополнительная информация о точности. Если вы действительно хотите достичь этой цели, у вас нет другого выбора, кроме как написать свой собственный класс в качестве обертки вокруг OffsetDateTime и точности (выраженной как ChronoUnit -enum).

В противном случае, если вы всегда хотите сохранить точность в миллисекундах для своего вывода, вам не следует использовать метод toString(), но специальный форматировщик.В Java-8 это будет выглядеть так:

OffsetDateTime odt = OffsetDateTime.parse("2015-02-05T02:05:17+00:00"); 
String dateTimeWithMilliSecondPrecision = 
    odt.format(DateTimeFormatter.ofPattern("uuuu-MM-dd'T'HH:mm:ss.SSSxxx")); 
System.out.println(dateTimeWithMilliSecondPrecision); 
// output: 2015-02-05T02:05:17.000+00:00 
+0

@kapep благодарит за исправление опечаток –

Смежные вопросы