Вывод Java DateTimeFormatter.ISO_OFFSET_DATE_TIME отличается от Java Doc

из документа java 11 для ISO_OFFSET_DATE_TIME

Средство форматирования даты и времени ISO, которое форматирует или анализирует дату и время со смещением, например '2011-12-03T10:15:30+01:00'.

  1. Но когда я использую DateTimeFormatter с указанным выше форматированием, я вижу другой результат.
  2. Установка часового пояса для DateTimeFormatter, похоже, не имеет никакого эффекта.

Код ниже должен прояснить это -

      public void j8DateTimeWithFormatter() {
        DateTimeFormatter odtf = DateTimeFormatter.ISO_OFFSET_DATE_TIME;
        String zdt = ZonedDateTime.now().format(odtf);       
        System.out.println(zdt);  // Output 2021-06-06T22:44:28.4410102+05:30 //what is this 4410102, is it nano seconds or some thing else. How to not see this. 
       
        //further
        odtf.withZone(ZoneId.of("US/Eastern")); 
        zdt = ZonedDateTime.now().format(odtf); 
        //after setting the zoneid to EST why am i still seeing time in IST
        System.out.println(zdt);  // Output 2021-06-06T22:44:28.4430055+05:30
    }

Как это исправить? Пожалуйста посоветуй. Я хочу по-прежнему использовать ISO_OFFSET_DATE_TIME и посмотрите результат, как в документах - 2021-06-06T22:44:28-04: 00

2 ответа

Решение

что это за 4410102, это наносекунды или что-то еще. Как этого не увидеть.

Это доли секунды. Если вы не хотите его видеть, сократите значение до секунд.

      System.out.println(ZonedDateTime.now().truncatedTo(ChronoUnit.SECONDS).format(odtf));

после установки zoneid на EST, почему я все еще вижу время в IST

Так как DateTimeFormatter является неизменным, и вам нужно присвоить новое значение следующим образом:

      odtf = odtf.withZone(ZoneId.of("US/Eastern"));

Демо:

      import java.time.ZoneId;
import java.time.ZonedDateTime;
import java.time.format.DateTimeFormatter;
import java.time.temporal.ChronoUnit;

public class Main {
    public static void main(String[] args) {
        DateTimeFormatter dtf = DateTimeFormatter.ISO_OFFSET_DATE_TIME;
        ZonedDateTime zdt = ZonedDateTime.now();
        System.out.println(zdt.format(dtf));

        // If you do not want nano seconds
        zdt = zdt.truncatedTo(ChronoUnit.SECONDS);
        System.out.println(zdt.format(dtf));

        // Formatting to a different timezone
        dtf = dtf.withZone(ZoneId.of("US/Eastern"));
        System.out.println(ZonedDateTime.now().format(dtf));

        // However, I recommend
        ZonedDateTime zdtNewYork = zdt.withZoneSameInstant(ZoneId.of("America/New_York"));
        System.out.println(zdtNewYork);
    }
}

Выход:

      2021-06-06T18:45:06.604419+01:00
2021-06-06T18:45:06+01:00
2021-06-06T13:45:06.607643-04:00
2021-06-06T13:45:06-04:00[America/New_York]

Узнать больше о java.time, современный API даты и времени* из Trail: Date Time .


* По любой причине, если вам нужно придерживаться Java 6 или Java 7, вы можете использовать ThreeTen-Backport, который поддерживает большую часть функций java.time для Java 6 и 7. Если вы работаете над проектом Android и своим Android API уровень по-прежнему не соответствует Java-8, проверьте API-интерфейсы Java 8+, доступные через десугаринг, и Как использовать ThreeTenABP в Android Project .

Что ж, это предполагаемое поведение.

В документации используются слова «такой как», что означает, что данный пример является, в общем, примером, и поэтому результат может отличаться.

В документах упоминается, что формат состоит из ISO_LOCAL_DATE_TIME и смещения. ISO_LOCAL_DATE_TIME, в свою очередь, состоит из ISO_LOCAL_DATE, буквы «T» и ISO_LOCAL_TIME.

И если мы затем посмотрим на документы для ISO_LOCAL_TIME:

От одной до девяти цифр для наносекунды. Будет выведено столько цифр, сколько потребуется.

Вот оно. Формат по умолчанию выводит необходимые нано.

Другие вопросы по тегам