The Requirement is as below to display Day, Hour, and Minute from Total Minutes:
I am getting the Minutes from the Hardware device.
6050 minutes is displayed as: 4d 5h (it is 4 days 4 hours and 50 minutes, 50 minutes we round to 1 hour)
6090 minutes is displayed as: 4d 6h (it is 4 days 5 hours and 30 minutes, 30 minutes we round to 1 hour)
6089 minutes is displayed as 4d 5h (it is 4 days 5 hours and 29 minutes, 29 minutes we round to 0 hours)
Other thing to take care is 0d 0h and 0m should be display as 0m.
One more thing is : If total hour is > 100, it should display without minute.
So far I have tried to achive it as below but not getting proper output:
fun minutesToDaysHoursMinutes(time: Double): String? {
val hourFromMinute: Double = time * 60.0
val d: Duration = Duration.ofMinutes(time.toLong())
val days: Long = d.toDays()
val hours: Long = d.toHours() % 24
val minutes: Long = d.toMinutes() % 60
if (hourFromMinute > 100) {
if (minutes >= 30) {
if (days == 0L && hours != 0L) {
return String.format("-h", hours)
}
if (days != 0L && hours == 0L) {
return String.format("-d", days)
}
return String.format("-d -h", days, (hours 1))
} else {
if (days == 0L && hours != 0L) {
return String.format("-h", hours)
}
if (days != 0L && hours == 0L) {
return String.format("-d", days)
}
if (days == 0L && hours == 0L) {
return String.format("-m", minutes)
}
return String.format("-d -h", days, hours)
}
} else {
var stringDays = "" days
if (stringDays.toInt()<=0) {
stringDays = ""
} else {
stringDays = stringDays "d"
}
var stringHours = "" hours
if (stringHours.toInt()<=0) {
stringHours = ""
} else {
stringHours = stringHours "h"
}
var stringMinutes = "" minutes
if (stringMinutes.toInt()<=0) {
stringMinutes = "0m"
} else {
stringMinutes = stringMinutes "m"
}
return stringDays " " stringHours " " stringMinutes
}
I can display proper values but Is there any better way to do so ? Thank you.
CodePudding user response:
Well, you have many if statements where roughly the same code is repeated. Also, your minutesToDaysHoursMinutes
method is doing two things: rounding and formatting the output.
I think you should put these two responsibilities into two separate methods.
The rounding
First, you could do the founding as follows:
Duration roundFromMinutesToHours(double minutes) {
var duration = Duration.ofMinutes((long) minutes);
long hoursToAdd = (duration.toMinutesPart() < 30 ? 0 : 1);
return duration.truncatedTo(ChronoUnit.HOURS).plusHours(hoursToAdd);
}
This method accepts the number of minutes, and then rounds up or down to hours, discarding the minutes value. Note that this method uses Duration::toMinutesPart
, which has been available since Java 9. toMinutesPart
doesn't return the total number of minutes, like toMinutes()
, but instead, returns the number of minutes within the hour. Note that this method returns a Duration
with a rounded-to-full-hours value.
Now you have a nice rounded Duration, which you can use in the following method.
The formatting
Then you could write the formatting of the Duration
as follows:
String formatDuration(Duration duration) {
if (duration.isZero()) {
return "0m";
}
var result = String.format("%sd %sh", duration.toDays(), duration.toHoursPart());
if (duration.toHours() <= 100) {
result = " 0m";
}
return result;
}
If the duration is 0 (thus originaly < 30 minutes), then return "0m". Otherwise, return either "xd yh" or "xd yh zm", where x, y and z are the days, hours and minutes respectively, based on whether the total number of hours is greater than 100.