0

I'm trying to convert a utc date time in local date time, but I have some problem the the decimal fraction. I call a web service the return a series of data. One of these data is the utc date time in this format I must the use this library org.threeten.bp, I can't use a different library.

2020-06-22T18:28:57.957535800Z

To converte utcFormat to Date,I have found this piece of code that it works fine

DateFormat utcFormat = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS'Z'");
utcFormat.setTimeZone(TimeZone.getTimeZone("UTC"));

Date date = utcFormat.parse("2012-08-15T22:56:02.038Z");

DateFormat pstFormat = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS");
pstFormat.setTimeZone(TimeZone.getTimeZone("ECT"));

System.out.println(pstFormat.format(date));

but it doesen't work well from my code, because return this date

2020-07-03T22:27:52.800

How you can see it's different. I did some test and if I leave only 3 decimal after dot, that part of code it will work fine. Have a look the example:

2020-06-22T18:28:57.800Z

return the right date time from ECT zone

2020-06-22T20:28:57.800

I am looking for a way to receive the utc dateTime with only three decimals or to change the utc dateTime by removing the excess decimals. With this last case I am not if it can be a good idea.

Scripta14
  • 463
  • 2
  • 8
  • 22
  • 2
    SimpleDateFormat doesn't support micro or nano seconds. It only supports milliseconds i.e. upto 3 decimal places after seconds. Check out https://stackoverflow.com/a/62037652/1776132 – Smile Jun 23 '20 at 13:26
  • I recommend you don’t use `SimpleDateFormat` and `Date`. Those classes are poorly designed and long outdated, the former in particular notoriously troublesome. Instead use `Instant` from [java.time, the modern Java date and time API](https://docs.oracle.com/javase/tutorial/datetime/). Also never hardcode `Z` as a literal in your format pattern string. It’s an offset (of 0 from UTC) and needs to be parsed as such. – Ole V.V. Jun 23 '20 at 17:03
  • Also don’t rely on three letter time zone abbreviations. While UTC may be unmistakable, many are ambiguous, including ECT, which may be for European Central Time (often CET) or for Ecuador Time. – Ole V.V. Jun 23 '20 at 17:07

2 Answers2

3

Your input format is standard so you can simply parse it to an Instant for example:

String input = "2020-06-22T18:28:57.957535800Z";
Instant date = Instant.parse(input);

If you want to get rid of the last 3 decimals (i.e. only keep the result to a microsecond precision), you can truncate the result:

Instant truncated = date.truncatedTo(ChronoUnit.MICROS);

Also note that the classes you use in your example (DateFormat, Date etc) are not part of threeten.

Basil Bourque
  • 303,325
  • 100
  • 852
  • 1,154
assylias
  • 321,522
  • 82
  • 660
  • 783
0

Here's an approach similar to yours but using classes from org.threeten.bp only instead of mixing it with java.util:

public static void main(String[] args) throws ParseException {
    String datetimeUtc = "2020-06-22T18:28:57.957535800Z";
    // parse it to a ZonedDateTime, this is default formatting ==> no formatter needed
    ZonedDateTime utcTime = ZonedDateTime.parse(datetimeUtc);
    // print the result
    System.out.println(utcTime);
    // convert it to another zone
    ZonedDateTime estTime = utcTime.withZoneSameInstant(ZoneId.of("Europe/Paris"));
    // print that, too
    System.out.println(estTime);
    // define a non-default output format
    DateTimeFormatter dtf = DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ss.SSS");
    // and print the estTime using that format
    System.out.println(estTime.format(dtf));
}

This outputs the following:

2020-06-22T18:28:57.957535800Z
2020-06-22T20:28:57.957535800+02:00[Europe/Paris]
2020-06-22T20:28:57.957
deHaar
  • 17,687
  • 10
  • 38
  • 51