0

I'm having trouble understanding getting timestamps, subtracting them, and being able to assign and use the difference in future calculations. I am using Java in Android Studio.

When I use SimpleDateFormat and Calendar, I'm able to get the current time in HH:mm:ss but I'm not sure how to subtract two of those timestamps from each other and convert the difference into seconds. My end goal is to take the difference, convert it into seconds, assign it to an int, and later compare the value to other, predetermined values. This is a project in Android Studio so I have buttons already set up to fetch the timestamps.

Example:
- Get a current timestamp, say 16:50:32
- Get a second timestamp in the near future, say 16:53:29 (roughly three minutes later)
- Subtract those two timestamps and store the value in seconds, so the final value would be 177 (seconds)
- have this value of 177 in a variable so that I can do more things with it.

I'm able to use the following code to get the timestamps

Calendar calendar = Calendar.getInstance();
SimpleDateFormat startTime = new SimpleDateFormat("HH:mm:ss");
timeTest = startTime.format(calendar.getTime());

SimpleDateFormat endTime = new SimpleDateFormat("HH:mm:ss");
timeTest2 = endTime.format(calendar.getTime());

But after getting two timestamps I do not know how to subtract them, convert them to seconds and store them in an int value.

Tep
  • 13
  • 3
  • 1
    Maybe you could use `System.currentTimeMillis()` at the start, end and then subtract them. Then convert to seconds. – Hawk Feb 26 '20 at 23:31
  • As an aside consider throwing away the long outmoded and notoriously troublesome `SimpleDateFormat` and friends, and adding [ThreeTenABP](https://github.com/JakeWharton/ThreeTenABP) to your Android project in order to use java.time, the modern Java date and time API. It is so much nicer to work with. – Ole V.V. Feb 27 '20 at 04:19
  • Please take a look into our help center for tips on increasing your chances of good answers. The first thing it says is: *Search, and research and keep track of what you find. Even if you don't find a useful answer elsewhere on the site, including links to related questions that* haven't *helped can help others in understanding how your question is different from the rest.* ([How do I ask a good question?](https://stackoverflow.com/help/how-to-ask)) – Ole V.V. Feb 27 '20 at 04:25
  • Does this answer your question? [In Java, how do I get the difference in seconds between 2 dates?](https://stackoverflow.com/questions/1970239/in-java-how-do-i-get-the-difference-in-seconds-between-2-dates) Please search for many more similar questions and answers. – Ole V.V. Feb 27 '20 at 04:31

3 Answers3

2

Are you using Java 8?

If so you could convert to Instants and get the Duration between them:

    Calendar cal = ...
    Calendar cal2 = ...
    Instant instantOne = cal.toInstant();
    Instant instanceTwo = cal2.toInstant();
    Duration between = Duration.between(instantOne, instanceTwo);
    long seconds = between.getSeconds();

I assumed there was a reason you're using Calendar to begin with (it passed to you without your control?) ... If not then you can just use Instant.now() from the get go and cut out pre Java 8 date/time classes

tomgeraghty3
  • 1,234
  • 6
  • 10
1

Here's one way you can easily do it using LocalDateTime.

LocalDateTime instance1 = LocalDateTime.now();
//Do stuff
LocalDateTime instance2 = LocalDateTime.now();
long elapsedTimeInSeconds = instance1.until(instance2, ChronoUnit.SECONDS);
System.out.println(elapsedTimeInSeconds);

Since you already have a timestamp, assuming it's in the form of a String you can convert it to a LocalDateTime like so:

String timestamp = "2012-08-15T22:56:02.038Z";
LocalDateTime instance = LocalDateTime.ofInstant(Instant.parse(timestamp), ZoneId.systemDefault());

Edit: Changed LocalTime to LocalDateTime to fix rollover issues with previous solution.

Tim Hunter
  • 826
  • 5
  • 10
  • 1
    While `LocalTime` is good for representing a time of day just like the strings in the question are supposed to (much better, indeed), they are not so good for difference calculation. You never know whether midnight is passed in between. It will also work incorrectly when summer time (DST) begins or ends. Allow me to suggest `ZonedDateTime` instead. – Ole V.V. Feb 27 '20 at 04:36
  • @OleV.V. Fair enough, mate. – Tim Hunter Feb 27 '20 at 13:58
  • @OleV.V. Thinking about it, `LocalDateTime` should work identically without the day rollover issues so I will just edit that in. – Tim Hunter Feb 27 '20 at 14:12
1

The good answer by tomgeraghty3 may be all that you need. I am contributing a supplement.

java.time and ThreeTenABP

If I understood correctly, you really had two requirements:

  1. You need to be able to represent the start and end times in HH:mm:ss format.
  2. You need the elapsed time between start and end in seconds.

Don’t represent your times as strings, though. Doing calculations on those is pretty hopeless. Represent your times by proper date-time objects. Only format into strings when you need to give string output.

    DateTimeFormatter timeFormatter = DateTimeFormatter.ofPattern("HH:mm:ss");

    ZonedDateTime start = ZonedDateTime.now(ZoneId.systemDefault());
    TimeUnit.SECONDS.sleep(175); // Simulate that time passes
    ZonedDateTime end = ZonedDateTime.now(ZoneId.systemDefault());

    long diffSeconds = ChronoUnit.SECONDS.between(start, end);

    System.out.printf("From %s until %s was %d seconds",
            start.format(timeFormatter), end.format(timeFormatter), diffSeconds);

Example run:

From 05:49:41 until 05:52:36 was 175 seconds

Of course to see it run, stick in a smaller number like 3 or 6 instead of 175 first.

If printing HH:mm:ss format was not a requirement, you may use Instant instead of ZonedDateTime as in the answer by tomgeraghty3. Since in Instant is independent of time zone you would then leave out the argument to the now method:

    Instant start = Instant.now();

Similarly for end.

Depending on the work you need to do on the value you may want to consider the Duration class to represent the difference rather then a simple count of seconds. This too is demonstrated in the answer by tomgeraghty3.

Question: Doesn’t java.time require Android API level 26?

java.time works nicely on both older and newer Android devices. It just requires at least Java 6.

  • In Java 8 and later and on newer Android devices (from API level 26) the modern API comes built-in.
  • In non-Android Java 6 and 7 get the ThreeTen Backport, the backport of the modern classes (ThreeTen for JSR 310; see the links at the bottom).
  • On (older) Android use the Android edition of ThreeTen Backport. It’s called ThreeTenABP. And make sure you import the date and time classes from org.threeten.bp with subpackages.

Links

Ole V.V.
  • 81,772
  • 15
  • 137
  • 161