How to convert milliseconds to "mm:ss:ms" format? [duplicate] - java

This question already has answers here:
How do I time a method's execution in Java?
(42 answers)
How to format a duration in java? (e.g format H:MM:SS)
(22 answers)
Closed 1 year ago.
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:
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!

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.

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
)

Related

Get 12 hours before and after current time

I'm having an issue working with time in Java. I don't really understand how to efficiently solve comparing the time of now and 12 hours before and after
I get a set of starting times for a show from an API and then compare that starting time with LocalTime.now(). It looks something like this:
SimpleDateFormat sdt = new SimpleDateFormat("HH:mm:ss");
String temp = sdt.format(Local.time(now));
LocalTime secondTime = LocalTime.parse(parts1[0]);
LocalTime firstTime = LocalTime.parse(temp);
int diff = (int) ((MINUTES.between(firstDay, secondDay) + 1440) % 1440);
if(diff <= 720){
return true;
}
Where my idea is that if the difference between the two times is smaller than 720 minutes (12 hours) I should get the correct output. And this works for the 12 hours before now. I thought I might need to swap the parameters of .between, to get the other side of the day. That counts it completely wrong (If the time now is 15:00:00 it would accept all the times until 22:00:00 the same day). Is this just a really bad way of comparing two times? Or is it just my math that lacks understanding of what I'm trying to do?
Thanks
Using the 'new' (not that new) Java 8 time API:
Instant now = Instant.now();
Instant hoursAfter = now.plus(12, ChronoUnit.HOURS);
Instant hoursBefore = now.minus(12, ChronoUnit.HOURS);
First, doing this kind of operations on java.time.LocalTime won't work! Or at least only if the time is "12:00:00" …
That is because you will have an over-/underflow when you add/substract 12 hours from any other time.
So your starting point should be to go for java.time.LocalDateTime (at least, although I would go for java.time.Instant). Now you can handle the over-/underflow, as you will get another day when adding or subtracting 12 hours.
How this works is shown in this anwswer: LocalDateTime allows nearly the same operations as Instant.

TimeDelta java?

I am trying to convert code from Python to Java. I need to rewrite the timedelta function in Java. Here is the code in Python:
def timeDate(date):
return (timedelta(seconds=date * 3600 % 86400))
Does anyone have any idea on how to make a function that acts the same?
double hours = 21.37865107050986;
long nanos = Math.round(hours * TimeUnit.HOURS.toNanos(1));
Duration d = Duration.ofNanos(nanos);
// Delete any whole days
d = d.minusDays(d.toDays());
System.out.println(d);
This prints:
PT21H22M43.143853836S
Which means: a duration of 21 hours 22 minutes 43.143853836 seconds.
Assumptions: I understand that you want a duration (the docs you link to say “A timedelta object represents a duration”). I have taken date to be a floating-point number of hours, and your modulo operation lead me to believe that you want the duration modulo 1 day (so 26 hours should come out as a duration of 2 hours).
The Duration class in Java is for durations, hence is the one that you should use. It doesn’t accept a floating point number for creation, so I converted your hours so nanoseconds and rounded to whole number. For the conversion I multiplied by the number of nanoseconds in 1 hour, which I got from the call to TimeUnit (this gives clearer and less error-prone code than multiplying out ourselves).
The code above will tacitly give incorrect results for numerically large numbers of hours, so you should check the range before using it. Up to 2 500 000 hours (100 000 days or nearly 300 years) you should be safe.
Please note: if date was a time of day and not a duration, it’s a completely different story. In this case you should use LocalTime in Java. It’s exactly for a time of day (without date and without time zone).
nanos = nanos % TimeUnit.DAYS.toNanos(1);
LocalTime timeOfDay = LocalTime.ofNanoOfDay(nanos);
System.out.println(timeOfDay);
21:22:43.143853836
Link: Documentation of the Duration class
As far as I know, Java doesn't have a built in DeltaTime function. However you can easily make your own.long startTime;
long delta; public void deltaTime(){ long currentTime = System.currentTimeMillis(); delta = currentTime - startTime;}
Whenever you want to start your DeltaTime timer, you just do time = System.currentTimeMillis;. This way, the variable "delta" is the amount of time between when you started the DeltaTime timer and when you end it using ClassNameHere.deltaTime();.
private static LocalTime timeDate(double d) {
//converts into a local time
return LocalTime.ofSecondOfDay((long)(d*3600%86400));
}
Input (d):
36.243356711275794
Output:
21:22:43

How to parse duration in format "HHmm" using JodaTime?

I'm trying to shift datetime by a Duration which I get in the format "HHmm", for example "0010" meaning 10 minutes.
I've found similar ticket (Parsing time strings like "1h 30min") but I can't make it work properly.
Here's the code:
PeriodFormatter hoursMinutes = new PeriodFormatterBuilder().appendHours().appendMinutes().toFormatter();
Duration duration = hoursMinutes.parsePeriod("0010").toStandardDuration();
duration.getStandardMinutes(); //Returns 600
For some reason, I get 600 minutes instead of 10. So it looks like the minutes were interpreted as hours, but I can't understand why. I've tried adding .maximumParsedDigits(2) for hours, but the result was the same.
Why is my code wrong? Is there some other way to initialize duration parser? Something, where I could just use the standard format like "HHmm"?
So the issue was really with the maximum parseddigits. I only had to add it before hours, not minutes. So the solution is this:
PeriodFormatter hoursMinutes =
new PeriodFormatterBuilder().maximumParsedDigits(2).appendHours().appendMinutes().toFormatter();
Duration duration = hoursMinutes.parsePeriod("0010").toStandardDuration();
duration.getStandardMinutes(); //Returns 10
According to the documentation:
getStandardMinutes
public long getStandardMinutes()
Gets the length of this duration in minutes assuming that there are the standard number of milliseconds in a minute. This method assumes that there are 60 seconds in a minute and 1000 milliseconds in a second. All currently supplied chronologies use this definition.
This returns getMillis() / 60000. The result is an integer division,
thus excess milliseconds are truncated.
Returns: the length of the duration in standard seconds
Seeing as 600 is actually 10 minutes in seconds (60 * 10), you got the answer you expected.

Getting difference between two Timestamp objects in Java

I'm working on a project, it's about parking and it contains a database. I have variable timestamp for time/date when car enter the parking, and one also for when the car is on the exit.
I want to get difference in hours (minute after every full hour is a new hour etc. 4 hours and 2 mins are same as 5 hours) so I can calculate price of the service (hours multiply by price per hour).
Help me pls, and thank you in advance
get difference in milliseconds and calculate as below
long timeDiff = endTime.getTime() - startTime.getTime()
int hours = (int)Math.ceil(timeDiff/1000*60*60) //In here we are converting milli seconds difference to hours and then if it is not an exact number we are converting that to the next integer
After obtaining the time value in milliseconds (e.g. using a Date object) use TimeUnit to get the difference in times:
TimeUnit.HOURS.convert(timeOut.getTime()-timeIn.getTime(), TimeUnit.MILLISECONDS);

Java - change Minutes and Seconds to time format? (mm:ss)

i started with total milliseconds, which I've converted to to total minutes and total seconds:
long minutes = TimeUnit.MILLISECONDS.toMinutes(itemDuration);
long seconds = TimeUnit.MILLISECONDS.toSeconds(itemDuration)
- TimeUnit.MINUTES.toSeconds(minutes);
Now I want to display the minutes and seconds in a mm:ss format (and if occasionally there are hours, then convert to hh:mm:ss format). how would i go about doing this?
thanks!
edit: I've tried using SimpleDateFormat, however it would display the wrong time in time zone that differ by half an hour vs a full hour. (ie: if the time zone was GMT +5:30 and the item duraction was 5 seconds, the app would display 30:05 instead of 00:05).. however it works fine for other time zones that differ by a full hour, such as GMT+5.
unless i'm doing something wrong with the SimpleDateFormat?
private static final SimpleDateFormat mLengthFormatter = new SimpleDateFormat("mm:ss", Locale.getDefault());
(also, just out of curiosity, if I use a SimpleDateFormat, and the number of minutes is greater than 2 digits, then what would happen? would it max out at 99?)
Could probably do it with a string formatter.
formatter.format("%2d:%2d", minutes,seconds);

Categories

Resources