DateTimeFormatter с фиксированной длиной нано-значения

Я не могу найти предопределенный DateTimeFormatter который печатает нано-второй раздел с одинаковым количеством цифр каждый раз. Я получаю шкафы ISO_LOCAL_TIME :

LocalDateTime.now().format(DateTimeFormatter.ISO_LOCAL_TIME) генерирует такие значения, как:

14:45:42.0496733
14:45:43.4205
14:45:45.6078279
14:45:45.623833

.4205 самом деле означает нано секунду .4205000 (или, точнее, .420500000 ), но нули в конце опущены. Я хотел бы предопределенный DateTimeFormatter который печатает второй нано-раздел с одинаковой шириной каждый раз, так как «отсутствующие» нули портят мои файлы журнала с вкладками. Итак, я ищу это:

14:45:42.0496733
14:45:43.4205000
14:45:45.6078279
14:45:45.6238330

Или это:

14:45:42.049673300
14:45:43.420500000
14:45:45.607827900
14:45:45.623833000

Я понимаю, что могу использовать String.format для добавления конечных нулей или что я могу создать свой собственный DateTimeFormatter используя new DateTimeFormatterBuilder().appendFraction(NANO_OF_SECOND, 7, 7, true) ... но я бы предпочел использовать что-то вне из коробки.

Всего 2 ответа


Вы можете определить свой собственный шаблон в DateTimeFormatter.ofPattern(String pattern) следующим образом:

Использование нано-секунд ( n ):

public static void main(String[] args) {
    DateTimeFormatter nineNanosDtf = DateTimeFormatter.ofPattern("HH:mm:ss.nnnnnnnnn");
    LocalDateTime now = LocalDateTime.now();
    System.out.println(now.format(nineNanosDtf));
}

который выводит 9 нано секунд: 19:44:28.791000000

или доли секунды ( S ):

public static void main(String[] args) {
    DateTimeFormatter nineNanosDtf = DateTimeFormatter.ofPattern("HH:mm:ss.SSSSSSSSS");
    LocalDateTime now = LocalDateTime.now();
    System.out.println(now.format(nineNanosDtf));
}

Я выбрал фиксированное количество 9 долей секунды в этом случае по SSSSSSSSS которое будет заполнено нулями, если нет других нано-значений для печати.

который выводит 19:43:49.592000000

РЕДАКТИРОВАТЬ

Я пробовал шаблон с одним n а также с 8, 9 и 10 n s несколько раз, например так:

public static void main(String[] args) {
    // two date time Strings
    String datetimeOne = "19:08:58.012345678"; // one with a leading zero nano
    String datetimeTwo = "19:08:58.123456789"; // and one without

    // several patterns that might be interesting
    DateTimeFormatter singleNPatternDtf = DateTimeFormatter.ofPattern("HH:mm:ss.n");
    DateTimeFormatter eightNsPatternDtf = DateTimeFormatter.ofPattern("HH:mm:ss.nnnnnnnn");
    DateTimeFormatter nineNsPatternDtf = DateTimeFormatter.ofPattern("HH:mm:ss.nnnnnnnnn");
    DateTimeFormatter tenNsPatternDtf = DateTimeFormatter.ofPattern("HH:mm:ss.nnnnnnnnnn");

    // parse the two Strings
    LocalTime localTimeOne = LocalTime.parse(datetimeOne, DateTimeFormatter.ISO_LOCAL_TIME);
    LocalTime localTimeTwo = LocalTime.parse(datetimeOne, DateTimeFormatter.ISO_LOCAL_TIME);

    // print / format both and LocalTime.now() with the single 'n' pattern
    System.out.println("1 * n:	" + localTimeOne.format(singleNPatternDtf) + "	—	"
            + localTimeTwo.format(singleNPatternDtf) + "	—	" 
            + LocalTime.now().format(singleNPatternDtf));
    // print / format both and LocalTime.now() with eight 'n's pattern
    System.out.println("8 * n:	" + localTimeOne.format(eightNsPatternDtf) + "	—	"
            + localTimeTwo.format(eightNsPatternDtf) + "	—	" 
            + LocalTime.now().format(eightNsPatternDtf));
    // print / format both and LocalTime.now() with nine 'n's pattern
    System.out.println("9 * n:	" + localTimeOne.format(nineNsPatternDtf) + "	—	"
            + localTimeTwo.format(nineNsPatternDtf) + "	—	" 
            + LocalTime.now().format(nineNsPatternDtf));
    // print / format both and LocalTime.now() with ten 'n's pattern
    System.out.println("10 * n:	" + localTimeOne.format(tenNsPatternDtf) + "	—	"
            + localTimeTwo.format(tenNsPatternDtf) + "	—	" 
            + LocalTime.now().format(tenNsPatternDtf));
}

Код выдает следующие данные (в большинстве случаев):

1 * n:  19:08:58.12345678   —   19:08:58.12345678   —   19:26:40.23000000
8 * n:  19:08:58.12345678   —   19:08:58.12345678   —   19:26:40.26000000
9 * n:  19:08:58.012345678  —   19:08:58.012345678  —   19:26:40.026000000
10 * n: 19:08:58.0012345678 —   19:08:58.0012345678 —   19:26:40.0026000000

Это означает значительную разницу в возвращаемом значении в зависимости от шаблона, предоставленного используемому DateTimeFormatter ...

К сожалению, шаблон с 8 n действительно не работал каждый раз.
Вместо этого иногда выдается Exception :

Exception in thread "main" java.time.DateTimeException:
Field NanoOfSecond cannot be printed as the value 155000000 exceeds the maximum print width of 8
    at java.time.format.DateTimeFormatterBuilder$NumberPrinterParser.format(Unknown Source)
    at java.time.format.DateTimeFormatterBuilder$CompositePrinterParser.format(Unknown Source)
    at java.time.format.DateTimeFormatter.formatTo(Unknown Source)
    at java.time.format.DateTimeFormatter.format(Unknown Source)
    at java.time.LocalDateTime.format(Unknown Source)

который указывает на недопустимый шаблон, поэтому рекомендовать тот, у кого восемь 'n', нельзя.

Решите сами, какой из них использовать, комментарий указывает на тот, который имеет девять n s.

Я бы (сейчас) предпочел бы это по сравнению с синглом или десятью.


Для 7 цифр и «из коробки» это возможно:

DateTimeFormatter test1 = DateTimeFormatter.ofPattern("HH:mm:ss.SSSSSSS");

Для 9-10 цифр (и из коробки) это решение:

DateTimeFormatter test2 = DateTimeFormatter.ofPattern("HH:mm:ss.nnnnnnnnnn");

(С менее чем 9 нано-цифрами вы java.time.DateTimeException: Field NanoOfSecond cannot be printed... в java.time.DateTimeException: Field NanoOfSecond cannot be printed... )


Использование:

//for(int i =0;i<100;i++) ...
LocalDateTime t1 = LocalDateTime.now();
System.out.println(t1.format(test1));
System.out.println(t1.format(test2));

... к сожалению, мне не удалось протестировать какие-либо временные метки с "самым низким значением nanos> 0":

16:05:23.124 // <- ISO_LOCAL_TIME
16:05:23.1240000 //<- test1
16:05:23.1240000000 //<- test2

Есть идеи?

10000