The Number:Time formatting is kind of a hack so it has limitations. It will only work for days under 31. At that point it goes back to zero.
The way it works is it takes epoch (i.e. 1970-01-01T00:00:00.000) and adds the Number:Time to that. So when you are formatting it you are really formatting 1970-01-05T01:02:03. Once you get to 32 days you are now in February so you have 1970-02-01T01:02:03.
And as was described in that thread, trying to use the Julian data isn’t going to work. So I think you need to use a transform unless you are certain that your uptime will never exceed 31 days.
The tranform that you posted in that thread isn’t working not because of units but because Nashorn JS was a lot more “forgiving” in how it converted various data types from one to another. Given the following in GraalVM JS:
(function(mins) {
var days = Math.floor(mins / (24 * 60));
mins = mins % (24 * 60);
var hours = Math.floor(mins / 60);
mins = mins % 60;
return days + "d, " + hours + "h, " + mins + "m";
})(input)
input
and therefore mins
is a String. They have always been a String but Nashorn auto converted the String to a Number because that’s what Math.floor wants. And frankly it’s a little shady about it because 123 s
isn’t a number, but Nashorn just ignored the s
.
ECMAScript 11 treats that as an error. If you want to do math with the input, you need to parse it.
But all is not lost. The JS Scripting helper library is available so we can use the tools available there and don’t have to mess with the math ourselves too much.
(function(durStr) {
const zeroPad = (num, places) => String(num).padStart(places, '0');
const dur = Quantity(durStr); // parse the String to a Quantity
const seconds = dur.toUnit('s').number; // convert the value to seconds and get the number
const durationObj = time.Duration.parse('PT'+seconds+'S'); // Create a Duration Object
const days = durationObj.toDays();
const hours = durationObj.minus(time.Duration.ofDays(days)).toHours(); // subtract off the days
const minutes = durationObj.minus(time.Duration.ofDays(days).plus(hours)); // subtract off the days and hours
return days + ':' + zeroPad(hours, 2) + ':' + zeroPad(minutes, 2);
})(input)
Or if you are OK with ISO8601 formatting you can just return the toString
of durationObj
but that’s not going to show days, just hours.
The Duration
built into Java is a little more convenient as it has getHoursOfDay()
and such which completely eliminates the need to do the math. But I like to stick to JS where I can. But that code would look something like:
(function(durStr) {
const zeroPad = (num, places) => String(num).padStart(places, '0');
const Duration = Java.type('java.time.Duration');
const dur = Quantity(durStr);
const seconds = dur.toUnit('s').number;
const durationObj = Duration.ofSeconds(seconds)
return durationObj.toDays() + ':' + zeroPad(durationObj.toHoursPart(), 2) + ':' + zeroPad(durationObj.toMinutesPart(), 2);
})(input)
Of if you just want to do the math youself:
(function(minsStr) {
var mins = Quantity(minStr).toUnit('min').number
var days = Math.floor(mins / (24 * 60));
mins = mins % (24 * 60);
var hours = Math.floor(mins / 60);
mins = mins % 60;
return days + "d, " + hours + "h, " + mins + "m";
})(input)