DateTimeFormatter с фиксированной длиной нано-значения - PullRequest
2 голосов
/ 15 января 2020

Я не могу найти предопределенный 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 ]

3 голосов
/ 15 января 2020

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

Используя nano-of-секунд (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

EDIT

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

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:\t" + localTimeOne.format(singleNPatternDtf) + "\t—\t"
            + localTimeTwo.format(singleNPatternDtf) + "\t—\t" 
            + LocalTime.now().format(singleNPatternDtf));
    // print / format both and LocalTime.now() with eight 'n's pattern
    System.out.println("8 * n:\t" + localTimeOne.format(eightNsPatternDtf) + "\t—\t"
            + localTimeTwo.format(eightNsPatternDtf) + "\t—\t" 
            + LocalTime.now().format(eightNsPatternDtf));
    // print / format both and LocalTime.now() with nine 'n's pattern
    System.out.println("9 * n:\t" + localTimeOne.format(nineNsPatternDtf) + "\t—\t"
            + localTimeTwo.format(nineNsPatternDtf) + "\t—\t" 
            + LocalTime.now().format(nineNsPatternDtf));
    // print / format both and LocalTime.now() with ten 'n's pattern
    System.out.println("10 * n:\t" + localTimeOne.format(tenNsPatternDtf) + "\t—\t"
            + localTimeTwo.format(tenNsPatternDtf) + "\t—\t" 
            + 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 с.

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

1 голос
/ 15 января 2020

Для 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...)


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

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

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

16:05:23.124 // <- ISO_LOCAL_TIME
16:05:23.1240000 //<- test1
16:05:23.1240000000 //<- test2
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...