Anne_Kim  
                (Anne Kim)
               
                 
              
                  
                    January 28, 2020,  5:34pm
                   
                   
              1 
               
             
            
              Hello,
The question is how to get the difference rounded to a day between the dates in a document? 
For example, if date1  = 2019-12-27T23:00:00.999 and date2  = 2019-12-28T01:00:00.999, the answer is 1 . 
I'm already using  this:
doc['room_created_at'].value.millis - doc['player_created_at'].value.millis) / 1000 / 60 / 60 / 24
 
but it doesnt show the "calendar"  difference.
             
            
               
               
               
            
            
           
          
            
              
                spinscale  
                (Alexander Reelsen)
               
              
                  
                    January 29, 2020,  3:15pm
                   
                   
              2 
               
             
            
              try something like doc['room_created_at'].value.toInstant().minus(doc['player_created_at'].value.toInstant()).toEpochMilli() (on top of my head and untested, also depends on the ES version being used)
             
            
               
               
               
            
            
           
          
            
              
                Anne_Kim  
                (Anne Kim)
               
              
                  
                    January 30, 2020,  4:58pm
                   
                   
              3 
               
             
            
              The following code is the solution:
doc['room_created_at'].value.millis / 1000 / 60 / 60 / 24 - doc['player_created_at'].value.millis / 1000 / 60 / 60 / 24
 
             
            
               
               
               
            
            
           
          
            
              
                Anne_Kim  
                (Anne Kim)
               
                 
              
                  
                    February 3, 2020, 11:34am
                   
                   
              4 
               
             
            
              What do you think about the following? To solve the problem, I've written the script :
if (doc['player_created_at'].size() != 0) {
    return (doc['start_at'].value.millis / 1000 / 60 / 60 / 24 - doc['player_created_at'].value.millis / 1000 / 60 / 60 / 24)
} else {
    return null
}
 
but the script gives different results. For example, if the difference between the dates is 3d 3h 1m 56s  , it calculates as 3  days. But if the difference is 3d 9h 17m 6s  , the difference calculated is 4  days (see the screenshot). What's the reason? 
P.S. I've tried to use the 
ceil  function, but it works only in X-Pack, so it's not supported in my version of Kibana
            
 
            
               
               
               
            
            
           
          
            
              
                spinscale  
                (Alexander Reelsen)
               
              
                  
                    February 3, 2020,  3:12pm
                   
                   
              5 
               
             
            
              keep in mind that this uses the same division logic than java. All of those values are integers, so this is doing integer division with rounding.
             
            
               
               
               
            
            
           
          
            
              
                Anne_Kim  
                (Anne Kim)
               
              
                  
                    February 4, 2020,  8:38am
                   
                   
              6 
               
             
            
              Can it be a solution that calculates the difference as float number and than returns an "integer + 1"? I've written a script, but it doesn work cause of error in casting float-->integer
             
            
               
               
               
            
            
           
          
            
              
                spinscale  
                (Alexander Reelsen)
               
              
                  
                    February 4, 2020,  9:02am
                   
                   
              7 
               
             
            
              Hm, I think instead of doing calculations yourself, how about
Duration.between(doc['room_created_at'].value.toInstant(), doc['player_created_at'].value.toInstant()).ofDays();
 
This way you don't need to worry about calculations yourself and their order or their casting...
             
            
               
               
               
            
            
           
          
            
              
                Anne_Kim  
                (Anne Kim)
               
              
                  
                    February 4, 2020,  2:27pm
                   
                   
              8 
               
             
            
              It shows that the method is not found:
{
 "root_cause": [
  {
   "type": "script_exception",
   "reason": "compile error",
   "script_stack": [
    "... d_at'].value.toInstant()).ofDays())\r\n    } else {\r ...",
    "                             ^---- HERE"
   ],
   "script": "if (doc['room_created_at'].size() != 0) {\r\n    if (doc['player_created_at'].size() != 0) {\r\n        return (Duration.between(doc['room_created_at'].value.toInstant(), doc['player_created_at'].value.toInstant()).ofDays())\r\n    } else {\r\n        return null\r\n    }\r\n} else {\r\n    return null\r\n}",
   "lang": "painless"
  }
 ],
 "type": "search_phase_execution_exception",
 "reason": "all shards failed",
 "phase": "query",
 "grouped": true,
 "failed_shards": [
  {
   "shard": 0,
   "index": "gameplay_stat",
   "node": "pZQAw2krTHuIGJxi8862ug",
   "reason": {
    "type": "script_exception",
    "reason": "compile error",
    "script_stack": [
     "... d_at'].value.toInstant()).ofDays())\r\n    } else {\r ...",
     "                             ^---- HERE"
    ],
    "script": "if (doc['room_created_at'].size() != 0) {\r\n    if (doc['player_created_at'].size() != 0) {\r\n        return (Duration.between(doc['room_created_at'].value.toInstant(), doc['player_created_at'].value.toInstant()).ofDays())\r\n    } else {\r\n        return null\r\n    }\r\n} else {\r\n    return null\r\n}",
    "lang": "painless",
    "caused_by": {
     "type": "illegal_argument_exception",
     "reason": "method [java.time.Duration, ofDays/0] not found"
    }
   }
  }
 ]
}
 
How can the  toEpochDay() be used?
             
            
               
               
               
            
            
           
          
            
              
                spinscale  
                (Alexander Reelsen)
               
              
                  
                    February 5, 2020,  9:26am
                   
                   
              9 
               
             
            
              Try this using .toDays()
DELETE test
PUT test/_doc/1?refresh
{
  "room_created_at" : "2020-02-01T12:34:56.789Z",
  "player_created_at" : "2020-01-01T12:34:56.789Z"
}
GET test/_search
{
  "script_fields": {
    "scripted_filter": {
      "script": {
        "source": "Math.abs(Duration.between(doc['room_created_at'].value.toInstant(), doc['player_created_at'].value.toInstant()).toDays());",
        "lang": "painless"
      }
    }
  }
}
 
             
            
               
               
               
            
            
           
          
            
              
                Anne_Kim  
                (Anne Kim)
               
              
                  
                    February 6, 2020, 11:35am
                   
                   
              10 
               
             
            
              What do you think about this? (it works)
if (doc['room_created_at'].size() != 0) {
    if (doc['player_created_at'].size() != 0) {
        Instant p = Instant.ofEpochMilli(doc['player_created_at'].value.millis);
        Instant r = Instant.ofEpochMilli(doc['room_created_at'].value.millis);
        LocalDateTime ztp = LocalDateTime.ofInstant(p, ZoneId.of('Europe/Kiev'));
        LocalDateTime ztr = LocalDateTime.ofInstant(r, ZoneId.of('Europe/Kiev'));
        LocalDate localp = ztp.toLocalDate();
        LocalDate localr = ztr.toLocalDate();
        long dayp = localp.toEpochDay();
        long dayr = localr.toEpochDay();
        return (dayr-dayp)
    } else {
        return (-1)
    }
} else {
    return (-1)
}
 
             
            
               
               
               
            
            
           
          
            
              
                spinscale  
                (Alexander Reelsen)
               
              
                  
                    February 7, 2020,  2:11pm
                   
                   
              11 
               
             
            
              it sounds like there are a few additional calls for dates, but if it solves your problem properly, I wouldnt too much about it and go with it for now 
             
            
               
               
               
            
            
           
          
            
              
                Anne_Kim  
                (Anne Kim)
               
              
                  
                    February 7, 2020,  3:21pm
                   
                   
              12 
               
             
            
              So may be you have an idea how to optimize it?
             
            
               
               
               
            
            
           
          
            
              
                system  
                (system)
                  Closed 
               
              
                  
                    March 6, 2020,  3:21pm
                   
                   
              13 
               
             
            
              This topic was automatically closed 28 days after the last reply. New replies are no longer allowed.