1

I'm working on a program where I search through two text files and compare them (It's a task from JetBrains Academy). At the end I'm tasked to output the time it took to execute this, in the format of "mm:ss:ms". Picture as reference:

1

This is the code I've written to try to achieve this. I imagine it's pretty far from correct, so I apologize for this, I have been learning Kotlin and programming for not long.

val millis = System.currentTimeMillis()
val time = String.format("%1\$tM min. %1\$tS sec. %1\$tL ms.", millis);

println("Start searching...")
println("Found $number. Time taken: $time ")

The output I get is this:

> Start searching...
Found 864 / 864. Time taken: 19 min. 53 sec. 611 ms. 

The minutes and seconds are wrong, as it took less than a second. I have doubts about the ms, as they would fit on how much time it took. Can someone help me with what I'm doing wrong? Thanks!

Pauliecode
  • 107
  • 2
  • 9

2 Answers2

3

From System.currentTimeMillis():

Returns the difference, measured in milliseconds, between the current time and midnight, January 1, 1970 UTC.

So what you see in your output is the Hh:mm:ss portion of the time taken between 1970-01-01T00:00:00 up until now.

What you actually want is the taken time i.e the difference between start and end of your time measurement.

val start = System.currentTimeMillis()

// do your processing

val end = System.currentTimeMillis()
val time = String.format("%1$tM min. %1$tS sec. %1$tL ms.", end - start)

This should give you an appropriate output.


As noted in the comments weird stuff happens in some timezones. And String.format() seems to be quite unconfigurable (at least I didn't find anything).

If you really want to be on the safe side, you can use the answer suggested by @SergeyAfinogenov, but with some minor tweaks:

val minutes = duration.getSeconds() / 60
val seconds = duration.getSeconds() - minutes * 60
val millis = duration.getNano() / 1_000_000
val time = String.format("%d min. %d sec. %d ms.%n", minutes, seconds, millis)

This effectively manually calculates the different parts (minutes, seconds, millis) from the Duration and then formats them accordingly.

Lino
  • 19,604
  • 6
  • 47
  • 65
  • Thank you! This was definitely a very stupid question from me. I realized more or less where the mistake was shortly after posting it, now with your answer I see it very clear. Thanks for taking the time! – Pauliecode May 18 '21 at 11:05
  • 1
    Don’t do your own time math. Leave it to the `Duration` class to do it (or the `TimeUnit` enum if not on Java 8 or 9 or higher). – Ole V.V. May 19 '21 at 04:22
0

I would prefer to use Instant and ChronoUnit classes:

val now   = Instant.now()
//doing something
val later = Instant.now()

val time = String.format("%02d min. %02d sec. %03d ms.",
                          ChronoUnit.MINUTES.between(now,later),
                          ChronoUnit.SECONDS.between(now,later)%60,
                          ChronoUnit.MILLIS.between(now,later)%1000
                         )
Sergey Afinogenov
  • 2,137
  • 4
  • 13