-1

In our database, we have few long values like below

modified=1636334664000
created=1636334664000

if i use below code to convert, it doesnt show the format in millisec in it, it shows only up to seconds. i have used below code

long modified = 1636334664000l;
LocalDateTime ldt = LocalDateTime.ofInstant(
        Instant.ofEpochMilli(modified), ZoneId.systemDefault());
LocalDateTime dateTime = LocalDateTime.parse(ldt.toString());
dateTime = dateTime.atZone(ZoneId.systemDefault())
        .withZoneSameInstant(ZoneOffset.UTC)
        .toLocalDateTime();
Instant insStr = dateTime.toInstant(ZoneOffset.UTC);

this gives me output as "2021-11-08T01:24:24Z" but i was expecting as "2021-11-08T01:24:24.000Z".

used Java 8 date conversion as above.

Ole V.V.
  • 81,772
  • 15
  • 137
  • 161
Ramesh
  • 7
  • 4
  • 1
    An `Instant` cannot have a format. It cannot have or not have `.000` as fraction of second. Its `toString` method prints a fraction if it is non-zero and omits it if it is zero. Related question [here](https://stackoverflow.com/questions/53314552/java-instant-to-localdatetime-trailing-zero) and [here](https://stackoverflow.com/questions/58649073/array-of-instants-from-strings). – Ole V.V. Feb 14 '23 at 19:45
  • Also you are overcomplicating thingfs with your conversions. And also you haven’t got any good use for `LocalDateTime` (a much over-used class). To have `.000` printed you need to format your datetime value into a string. `Instant` cannot be formatted, so convert to an `OffsetDateTime` in UTC and format it: `Instant .ofEpochMilli(1_636_334_664_000L) .atOffset(ZoneOffset.UTC) .format(DateTimeFormatter.ofPattern("uuuu-MM-dd'T'HH:mm:ss.SSSX"))`. Result: `2021-11-08T01:24:24.000Z`. – Ole V.V. Feb 14 '23 at 19:51
  • And a detail I find worth considering: use upper case `L` to mark o `long`. It is so easy to confuse lower case `l` with digit `1`. – Ole V.V. Feb 14 '23 at 19:53
  • Also I cannot reproduce. I get a compile error from your code: *'parse(java.lang.CharSequence)' in 'java.time.LocalDateTime' cannot be applied to '(java.time.LocalDateTime)'* – Ole V.V. Feb 14 '23 at 20:16
  • `1636334664000l` has one too many digits. Presumably you meant `163633466400l`. – Basil Bourque Feb 14 '23 at 21:05
  • By “expecting as "2021-11-08T01:24:24.000Z".” did you mean “expecting as "2021-11-08T01:24:24.001Z".” with a millisecond in the fraction? – Basil Bourque Feb 14 '23 at 21:08
  • 1
    Please take more care when posting on Stack Overflow. Such careless typos in important example data is confusing, and may waste the time of those whose help you are requesting. – Basil Bourque Feb 14 '23 at 21:12
  • @BasilBourque You are confirming what i said. :-) `1636334664000l` has not got too many digits. It’s confusingly got a trailing lower case letter l (without which Java would not accept it as a literal). It does correspond to what the OP says, 2021-11-08T01:24:24Z (with zero fraction of second). – Ole V.V. Feb 15 '23 at 05:55
  • thanks @OleV.V. your given solution is working now if input is long but if the input is instance of LocalDateTime, how can i acheive similar output format with .000Z ? – Ramesh Feb 15 '23 at 20:07
  • Thanks @BasilBourque i have fixed compile issues, can u suggest how can i achieve .000Z if the input is localDateTime object instead of long as for long we got the solution above. – Ramesh Feb 15 '23 at 20:13
  • `ldt .atZone(ZoneId.systemDefault()) .withZoneSameInstant(ZoneOffset.UTC) .format(DateTimeFormatter.ofPattern("uuuu-MM-dd'T'HH:mm:ss.SSSX"))`. This converts to UTC and formats using the same formatter as above, that is, with `.000Z` if the fraction of second is zero. I recommend you extract the formatter into a constant. – Ole V.V. Feb 16 '23 at 04:54

1 Answers1

0

tl;dr

After correcting multiple typos in the example data of your Question, we find no errors, no surprises, when running the code. Your millisecond appears as expected.

Instant.ofEpochMilli( 1_636_334_664_001L ).toString()

2021-11-08T01:24:24.001Z

LocalDateTime not helpful in your case

LocalDateTime is the wrong class to use here. That class represents a date with time-of-day but lacks the context of a time zone or offset-from-UTC. So that class cannot represent a moment, a specific point on the timeline.

To track moments use:

  • Instant
  • OffsetDateTime
  • ZonedDateTime

Use Instant

Assuming your long values represent a count of milliseconds since the epoch reference of first moment of 1970 in UTC, 1970-01-01T00:00Z, use Instant.ofEpochMilli.

Your 1636334664000l example presumably has a typo, one too many zero digits. I will go with 163633466400l.

When hard-coding such long values, use the optional underscore (_) digit grouping feature in Java. And append an L to ensure parsing as a long primitive.

Instant created = Instant.ofEpochMilli( 1_636_334_664_000L ) ;
Instant modified = Instant.ofEpochMilli( 1_636_334_664_001L ) ;

Calculate elapsed time.

Duration duration = Duration.between( created , modified ) ;

We expect to see a single millisecond as our result. The result is presented in standard ISO 8601 format.

Dump to console.

System.out.println( created ) ;
System.out.println( modified ) ;
System.out.println( duration ) ;

Execute at Ideone.com. We see your expected fractional second, a millisecond.

2021-11-08T01:24:24Z
2021-11-08T01:24:24.001Z
PT0.001S

ZonedDateTime

See that same moment through the wall-clock time of a particular time zone.

ZoneId z = ZoneId.of( "Asia/Tokyo" ) ;
ZonedDateTime zdtModifiedTokyo = instant.atZone( z ) ;

We continue to see your fractional second, a single millisecond.

zdtModifiedTokyo.toString(): 2021-11-08T10:24:24.001+09:00[Asia/Tokyo]

Basil Bourque
  • 303,325
  • 100
  • 852
  • 1,154
  • There’s a wealth of good information here, thanks. I think the OP meant to ask, though, why are they not getting the expected output of `2021-11-08T01:24:24.000Z` with a printed decimal fraction of `.000` (three zeroes)? – Ole V.V. Feb 15 '23 at 05:59