2

I have a string "2020-03-25T22:00:00.000Z" which i want to convert to OffsetDateTime. Below is the code I tried but when I pass milisecond as 000 then it is not reflecting in OffsetDateTime.

OffsetDateTime offsetDateTime=OffsetDateTime.parse("2020-03-25T22:00:01.123Z", 
DateTimeFormatter.ISO_OFFSET_DATE_TIME);
print(offsetDateTime)
//Output: 2020-03-25T22:00:01.123Z

But when mili is 000 then

OffsetDateTime offsetDateTime=OffsetDateTime.parse("2020-03-25T22:00:01.000Z", 
DateTimeFormatter.ISO_OFFSET_DATE_TIME);
print(offsetDateTime)

//Output: 2020-03-25T22:01Z (mili second is missing)

I tried custom formattter also but it behave same

OffsetDateTime.parse("2020-03-25T22:00:00.123Z",
           DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ss.SSSX"));

Can anyone please help me out

Lino
  • 19,604
  • 6
  • 47
  • 65
amit kumar
  • 59
  • 1
  • 1
  • 11
  • 2
    *"milisecond as 000 then it is not reflecting in OffsetDateTime"* Sure it is, because an [`OffsetDateTime`](https://docs.oracle.com/javase/8/docs/api/java/time/OffsetDateTime.html) "stores all date and time fields, **to a precision of nanoseconds**, as well as the offset from UTC/Greenwich" *(so says the javadoc)*. Changing how you *parse* a string into an `OffsetDateTime` doesn't change that, it always has a precision of nanosecond. The built-in format used when calling `toString()` will however suppress seconds and fractional seconds *(so says the javadoc)*. **Read the documentation**. – Andreas Jul 14 '20 at 08:23

2 Answers2

6

You have to remember that the format you used to parse the ISO-String may not be the same format used for converting the date-time object back to a String.

When you print the offset date time like this:

System.out.println(odt);

Then the OffsetDateTime.toString() method will be called, and from its documentation:

Outputs this date-time as a String, such as 2007-12-03T10:15:30+01:00. The output will be one of the following ISO-8601 formats:

  • uuuu-MM-dd'T'HH:mmXXXXX
  • uuuu-MM-dd'T'HH:mm:ssXXXXX
  • uuuu-MM-dd'T'HH:mm:ss.SSSXXXXX
  • uuuu-MM-dd'T'HH:mm:ss.SSSSSSXXXXX
  • uuuu-MM-dd'T'HH:mm:ss.SSSSSSSSSXXXXX

The format used will be the shortest that outputs the full value of the time where the omitted parts are implied to be zero.

Again, keep in mind that any class in the java.time package will not have a format, all those classes consist of some long fields which represent milliseconds or days etc.

I possibly can't stress this enough, but that is the essence when working with date and time: java.time classes do not have a format, you need to convert them into an appropriate format.

So if you always want to have the full value, then you simply need to format the OffsetDateTime to a String before you print it.

// best is to store that in a static variable
DateTimeFormatter dtf = DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ss.SSSX");

// parse using our custom formatter
OffsetDateTime odt = OffsetDateTime.parse("2020-03-25T22:00:00.000Z", dtf);

// print using our custom formatter
String formatted = odt.format(dtf);
System.out.println(formatted);

Which outputs:

2020-03-25T22:00:00.000Z
Lino
  • 19,604
  • 6
  • 47
  • 65
  • As stated in the question seems like OP receives the same output when formatting their date with a custom format string – Markiian Benovskyi Jul 14 '20 at 08:04
  • 1
    @MarkiianBenovskyi They **parse** the string with a custom formatter, but they've never showed how they print it. – Lino Jul 14 '20 at 08:05
  • You are doing odt.format(dtf) but I want to print the odt(OffsetDateTime).If you print odt then you wont get the milis. – amit kumar Jul 14 '20 at 08:05
  • @amitkumar remember that a `OffsetDateTime` has **no** format, you need to give it one. So *simply print it* won't work, you have to **always** provide that formatter: `odt.format(dtf)` – Lino Jul 14 '20 at 08:08
  • 1
    @Lino-Votedon'tsayThanks by default, method `toString()` on OffsetDateTime returns an ISO string: https://docs.oracle.com/javase/8/docs/api/java/time/OffsetDateTime.html#toString-- – Markiian Benovskyi Jul 14 '20 at 08:15
-1

I ran into the same issue a while ago, and there is actually an open thread on the Jackson module GitHub page here: https://github.com/FasterXML/jackson-modules-java8/issues/76

As you can see from this thread it seems to be an issue in the design of the Jackson module itself.

You should not be worried that the milliseconds are missing. It is designed to omit trailing zeroes in the ISO string to save time and memory, I think.

In my opinion this should be customizable behaviour.

You can find the exact same question and problem here: https://stackoverflow.com/a/52191521/4697963

Worth having a look and reading that thread.

marc_s
  • 732,580
  • 175
  • 1,330
  • 1,459
Markiian Benovskyi
  • 2,137
  • 22
  • 29