Java LocalDateTime.parse с точностью до миллисекунды, но необязательная точности микросекунды

Шейн Rowatt:

Есть ли способ, чтобы создать шаблон LocalDateTime, который будет анализировать дату / время, которое имеет по крайней мере, миллисекунду точность, но по желанию микросекунды точности то есть в следующей дате миллисекунды / время разобранного в порядке, но второй один в микросекундах терпит неудачу. Я думал, что дополнительные индикаторы в шаблоне «[» «]» позволило бы эту работу:

DateTimeFormatter DATE_TIME_FORMATTER = 
    DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss.SSS[SSS]");
System.out.println(LocalDateTime.parse("2019-02-14 11:04:52.784", DATE_TIME_FORMATTER));     
System.out.println(LocalDateTime.parse("2019-02-14 11:04:52.784108", DATE_TIME_FORMATTER));
Ole VV:

Hack нет. 1

    String withMillis = "2019-02-14 11:04:52.784";
    String withMicros = "2019-02-14 11:04:52.784108";

    System.out.println(LocalDateTime.parse(withMillis.replace(' ', 'T')));
    System.out.println(LocalDateTime.parse(withMicros.replace(' ', 'T')));
2019-02-14T11:04:52.784
2019-02-14T11:04:52.784108

Когда мы заменяем пространство в середине вашей струны с T, струнными образом соответствует ISO 8601, стандартный формат , что LocalDateTimeи другие классы java.time синтаксического анализа (а также печать) , как их по умолчанию, то есть без какого - либо явного форматировщика , Таким образом , это простое решение.

Hack нет. 2

Что - то вроде того, что вы пытались можно работать. Только вы не можете разделить последовательность SSSSSSс квадратной скобкой в середине.

static final DateTimeFormatter DATE_TIME_FORMATTER = 
        DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss.[SSSSSS][SSS]");

А потом:

    System.out.println(LocalDateTime.parse(withMillis, DATE_TIME_FORMATTER));     
    System.out.println(LocalDateTime.parse(withMicros, DATE_TIME_FORMATTER));

Уточняем необязательно 6 знаков после запятой , а затем при необходимости 3 знаков после запятой. Нам нужен этот порядок. Если мы [SSS][SSSSSS]и попытаться разобрать 6 знаков после запятой, форматировщик сначала разобрать 3 , а затем бросить исключение , потому что он не может разобрать оставшиеся 3 с SSSSSS. Это немного рубить , так как он также будет принимать десятичную точку без десятичных знаков на всех, и, вероятно , выдавать сообщение об ошибке очень запутанной (или , возможно , даже дать неправильный результат) , если дать ему 9 знаков после запятой.

Хорошее решение: использовать построитель

static final DateTimeFormatter DATE_TIME_FORMATTER = 
        new DateTimeFormatterBuilder().append(DateTimeFormatter.ISO_LOCAL_DATE)
                .appendLiteral(' ')
                .appendPattern("HH:mm:ss")
                .appendFraction(ChronoField.NANO_OF_SECOND, 1, 9, true)
                .toFormatter();

Здесь я указал как минимум 1 и максимум 9 знаков после запятой после десятичной точки. Вы можете указать 3 и 6, если вы предпочитаете. Это, конечно, принимать 4 или 5 тоже.

Ссылка: Статья Википедии: ISO 8601

рекомендация

отhttp://43.154.161.224:23101/article/api/json?id=232155&siteId=1