Почему Instant.now () иногда форматируется по-другому? - PullRequest
0 голосов
/ 25 мая 2018

У меня есть код, который выглядит следующим образом:

String PROPER_DATE_FORMAT = "yyyy-MM-dd";
String format = "yyyy-MM-dd'T'HH:mm:ss.SSSX";

SimpleDateFormat sdf = new SimpleDateFormat(format);
Date d = sdf.parse(Instant.now().toString());
SimpleDateFormat properFormat = new SimpleDateFormat(PROPER_DATE_FORMAT);
String formatterDate = properFormat.format(d);

Сейчас, в большинстве случаев, этот код работает, но время от времени я получаю Instant.now (), возвращая 2018-05-25T18:56:09Z, а затемон выдаст исключение, т.к. формат не соответствует.

Почему иногда это противоречиво?

Исключение составляет java.lang.RuntimeException: java.text.ParseException: Unparseable date: "2018-05-25T18:56:09Z"

Обычно, когда Instant.now().toString() возвращает строку с указанным выше форматом.Опять же, этот код работает большую часть времени, но бывают случаи, когда он не работает, и я удивляюсь, почему.

Я думал о том, было ли это потому, что в конце есть ноль, но простоне отображался, но я не уверен, потому что мне удалось получить значение 2018-05-25T20: 06: 58.900Z в результате Instant.now (). toString ()

Ответы [ 3 ]

0 голосов
/ 25 мая 2018

Ваш код не работает, потому что Instant.toString () задокументировано как

Используемый формат такой же, как DateTimeFormatter.ISO_INSTANT.

И в соответствии с DateTimeFormatter.html # ISO_INSTANT

Наносекунды выводит ноль, три, шесть или девять цифр при необходимости

Таким образом, у вас есть один шанс из тысячи получить Мгновенное действие, если миллис равны 000, а ваш код не работает.


В любом случае, ваш код неоправданно сложен и может быть заменен на

* 1022.*

Нет необходимости преобразовывать Instant в строку только для того, чтобы разобрать его в дату и затем снова преобразовать в строку.

0 голосов
/ 25 мая 2018

Чтобы ответить на ваш вопрос: « Instant.now () иногда форматируется по-другому? ».Давайте посмотрим, как был реализован Instance.now (). ToString ():

Instant.now (). ToString () source :

public String toString() {
    return DateTimeFormatter.ISO_INSTANT.format(this);
}

Javadoc из

DateTimeFormatter.ISO_INSTANT

https://docs.oracle.com/javase/8/docs/api/java/time/format/DateTimeFormatter.html#ISO_INSTANT

 When formatting, the second-of-minute is always output.
 The nano-of-second outputs zero, three, six or nine digits digits as necessary.

Из этого Javadoc мы понимаемчто Instance.now.toString () НЕ всегда 24 длины .

Если миллисекунд равно 000 -> Он будет производить формат, который вы получили:

2018-05-25T18: 56: 09Z - длина 20

НЕ

2018-05-25T18: 56: 09.000Z - длина 24

Isвсе понятно?

0 голосов
/ 25 мая 2018

Когда наносекунды равны нулю, они не включаются в форматированную строку.Таким образом, вывод будет отформатирован как «гггг-ММ-дд'Т'ЧЧ: мм: ссХ»

Вы можете увидеть разницу с:

public static void main(String[] args) throws ParseException {
        final Instant now = Instant.now();
        System.out.println("Now:\t" +  now);

        final Instant zeroedNow = now.with(ChronoField.NANO_OF_SECOND, 0);
        System.out.println("Zeroed:\t" + zeroedNow);
} 

Вывод выглядит как

Now:    2018-05-25T20:23:54.208Z
Zeroed: 2018-05-25T20:23:54Z
...