1

I am importing some sensor-data in my app over a server with JSON objects. They contain the value and time of the last measurement.

The time is in RFC3339 format send as a string, e.g. 2020-06-19T15:32:25.528Z.

Now, instead of displaying the last measurement´s time, I want to show the time difference between now and the measurement.

Searching I found neither a good solution to parse a RFC3339 timestamp string to an editable format, nor a way to calculate the difference to now. The only thing I saw is this article, but couldn´t manage to import the datetime-class in my app.

Can anybody help?

Anonymix
  • 13
  • 3

1 Answers1

1

Searching I found neither a good solution to parse a RFC3339 timestamp string to an editable format, nor a way to calculate the difference to now.

Use java.time.Duration

import java.time.Duration;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.time.ZonedDateTime;
import java.time.format.DateTimeFormatter;

public class Main {
    public static void main(String[] args) {
        // Given date-time
        LocalDateTime ldt = ZonedDateTime
                .parse("2020-06-19T15:32:25.528Z",
                        DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ss.SSSz").withZone(ZoneId.systemDefault()))
                .toLocalDateTime();

        // Get the duration between the given date-time and now
        Duration duration = Duration.between(ldt, LocalDateTime.now(ZoneId.systemDefault()));

        // Get hours, minutes, seconds from the Duration object
        System.out.printf("%d hours %d minutes %d seconds%n", duration.toHoursPart(), duration.toMinutesPart(),
                duration.toSecondsPart());
    }
}

Output:

3 hours 3 minutes 43 seconds

[Update]

Note that Duration#toXXXXXPart() e.g. Duration#toHoursPart() was introduced with Java-9. If you are using Java-8, you can use the calculation shown below:

import java.time.Duration;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.time.ZonedDateTime;
import java.time.format.DateTimeFormatter;

public class Main {
    public static void main(String[] args) {
        // Given date-time
        LocalDateTime ldt = ZonedDateTime
                .parse("2020-06-19T15:32:25.528Z",
                        DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ss.SSSz").withZone(ZoneId.systemDefault()))
                .toLocalDateTime();

        // Get the duration between the given date-time and now
        Duration duration = Duration.between(ldt, LocalDateTime.now(ZoneId.systemDefault()));

        // Get hours, minutes, seconds from the Duration object
        System.out.printf("%d hours %d minutes %d seconds%n", duration.toHoursPart(), duration.toMinutesPart(),
                duration.toSecondsPart());

        // For Java-8
        long hours = duration.toHours();
        int minutes = (int) ((duration.getSeconds() % (60 * 60)) / 60);
        int seconds = (int) (duration.getSeconds() % 60);
        System.out.printf("%d hours %d minutes %d seconds%n", hours, minutes, seconds);
    }
}

[Another Update] Courtesy Ole V.V.

import java.time.Duration;
import java.time.Instant;

public class Main {
    public static void main(String[] args) {
        // Given date-time
        Instant instant = Instant.parse("2020-06-19T15:32:25.528Z");

        // Get the duration between the given date-time and now
        Duration duration = Duration.between(instant, Instant.now());

        // Get hours, minutes, seconds from the Duration object
        System.out.printf("%d hours %d minutes %d seconds%n", duration.toHoursPart(), duration.toMinutesPart(),
                duration.toSecondsPart());
    }
}
Arvind Kumar Avinash
  • 71,965
  • 6
  • 74
  • 110
  • Thank you very much for the idea. There is only one problem: trying to implement your suggestion, Android Studio told me that there are **no** to...Part()-methods and even no toSeconds()-method. Although I used the same imports as you did and Oracle knows this methods. **Any idea why?** – Anonymix Jun 20 '20 at 09:11
  • @Anonymix - I've posted an update. I hope, it helps. Feel free to comment in case of any doubt/issue. – Arvind Kumar Avinash Jun 20 '20 at 09:50
  • (1) `LocalDateTime` is the wrong class to use since it ignores the offset in the source string, which is critical to know for a correct result. I recommend `Instant`. (2) You don’t need to specify a formatter. Each of `Instant.parse()` and the one-arg `OffsetDateTime.parse()` will parse the RFC-3339 string without any explicit formatter. – Ole V.V. Jun 20 '20 at 11:58
  • Thanks, @OleV.V. for the valuable suggestion as always. I've incorporated it in the answer as an update. – Arvind Kumar Avinash Jun 20 '20 at 12:09