Search code examples
elasticsearchkibanaelasticsearch-painless

painless to convert miliseconds to hh:mm:ss


In my index i have field called build duration with string type, Since i want to visualize the average of build_duration In Line chart Y-axis i want to select Average but if i select it shows The index pattern build-info does not contain any of the following compatible field types: number or histogram So for this reason i am looking to create scripted field to calculate the build duration average. currently it is in milliseconds ("build_duration" => "6409651") need help to convert into HH:mm:ss format. Have tried the below but it is not working. So can someone help me to work this? Any help would be highly appreciated.

enter image description here

Script:

String millisecondsString = doc['build_duration.keyword'].value;
long milliseconds = 1000000;
long minutes = (milliseconds / 1000) / 60;
long seconds = (milliseconds / 1000) % 60;
ZoneId z = ZoneId.of("Z");
Instant instant = Instant.ofEpochMilli(milliseconds);
LocalDateTime l = LocalDateTime.ofInstant(instant, z);
return l;

preview result

[
 {
  "_id": "37361323",
  "build_duration": "1062735",
  "test": [
   "1970-01-01T00:16:40.000Z"
  ]
 },
 {
  "_id": "37200499",
  "build_duration": "1446172",
  "test": [
   "1970-01-01T00:16:40.000Z"
  ]
 },

Kibana Discover field result.

enter image description here


Solution

  • Perhaps I'm missing something but it seems there's some confusion between a duration and a point in time.

    The duration of 6409651ms equals 1h 46m 49s. If you were to parse that as a date time (point in time) and didn't provide the date, ES would've put it at the beginning of the epoch (01.01.1970). While you could do that, it's somewhat unreasonable to think about durations and put them on a date axis...

    Now, if you want to "prettify" a millisecond duration (convert into the format hh:mm:ss), you could do that with this script:

    String millisecondsString = "6409651";
    long seconds = Long.parseLong(millisecondsString, 10) / 1000;
    long s = seconds % 60;
    long m = (seconds / 60) % 60;
    long h = (seconds / (60 * 60)) % 24;
    
    return String.format("%02d:%02d:%02d", new def[] { h, m, s });
    

    BTW the weird new def[] syntax in the last line comes from here.