joven
joven

Reputation: 391

Java DateTimeFormatter.ISO_OFFSET_DATE_TIME output differs from Java Doc

from java 11 doc for ISO_OFFSET_DATE_TIME

The ISO date-time formatter that formats or parses a date-time with an offset, such as '2011-12-03T10:15:30+01:00'.

  1. But when i use a DateTimeFormatter with the above formatting i am seeing different output.
  2. Setting timezone for DateTimeFormatter seems to have no effect.

Below code should clarify it -

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
    }

How to fix these? Please advice. I want to still use ISO_OFFSET_DATE_TIME and see the output as in docs - 2021-06-06T22:44:28-04:00

Upvotes: 2

Views: 1382

Answers (2)

Arvind Kumar Avinash
Arvind Kumar Avinash

Reputation: 79035

what is this 4410102, is it nano seconds or some thing else. How to not see this.

This is fraction-of-second. If you do not want to see it, truncate the value to seconds.

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

after setting the zoneid to EST why am i still seeing time in IST

Because DateTimeFormatter is immutable and you need to assign the new value as follows:

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

Demo:

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);
    }
}

Output:

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]

Learn more about java.time, the modern Date-Time API* from Trail: Date Time.


* For any reason, if you have to stick to Java 6 or Java 7, you can use ThreeTen-Backport which backports most of the java.time functionality to Java 6 & 7. If you are working for an Android project and your Android API level is still not compliant with Java-8, check Java 8+ APIs available through desugaring and How to use ThreeTenABP in Android Project.

Upvotes: 4

MC Emperor
MC Emperor

Reputation: 22977

Well, this is intended behavior.

The docs use the words "such as", which means the example is, well, an example, and thus the output may differ.

The docs mention that the format consists of ISO_LOCAL_DATE_TIME and the offset. The ISO_LOCAL_DATE_TIME in turn consists of the ISO_LOCAL_DATE, the letter 'T' and the ISO_LOCAL_TIME.

And if we then look at th docs for the ISO_LOCAL_TIME:

One to nine digits for the nano-of-second. As many digits will be output as required.

There it is. The format by default outputs necessary nanos.

Upvotes: 0

Related Questions