Two Datetimes, Calculate Duration
Two Datetimes, Calculate Duration

Calculates the duration between datetime A and B to output as numerical value (days), numerical value (hours), numerical value (minutes), or string value (h:mm). If B is the past time, a minus sign will be added. Date type also available.

2020-04-22 (C) Questetra, Inc. (MIT License)
https://support.questetra.com/addons/two-datetimes-calculate-duration/

Configs
  • A: Select DATETIME DATA *
  • B: Select DATETIME DATA *
  • C: Select NUMERIC DATA for Elapsed Days (update)
  • D: Select NUMERIC DATA for Elapsed Hours (update)
  • E: Select NUMERIC DATA for Elapsed Minutes (update)
  • F: Select STRING DATA for Elapsed Time h:mm (update)
Script
// Nashorn Script (engine type: 1)
// 
// Notes:
// The number of decimal places for Days and Hours depends on the numeric definition.
// "00:00" is applied when Date type data is compared.
// If Date subtype "YM", "-01" is added.
// If Date subtype "Y", "-01-01" is added.
// If Date subtype "MD", 'YYYY-' as of processing is added.
// 
// Notes(ja):
// Days や Hours の小数点以下桁数は、格納される数値型データ項目の定義に依ります。
// 日時型(Datetime)ではなく日付型(Date)データが比較される場合 00:00 が適用されます。
// 日付型(Date)でサブタイプが「YM」の場合、"01日" が補完されます。
// 日付型(Date)でサブタイプが「Y」の場合、"01月01日" が補完されます。
// 日付型(Date)でサブタイプが「MD」の場合、"処理時の年" が補完されます。


//////// START "main()" /////////////////////////////////////////////////////////////////
main();
function main(){ 

//// == Config Retrieving / 工程コンフィグの参照 ==
const dataIdA = configs.get( "conf_DataIdA" ) + "";  // config required
const dataIdB = configs.get( "conf_DataIdB" ) + "";  // config required
const dataIdC = configs.get( "conf_DataIdC" ) + "";  // config not required
const dataIdD = configs.get( "conf_DataIdD" ) + "";  // config not required
const dataIdE = configs.get( "conf_DataIdE" ) + "";  // config not required
const dataIdF = configs.get( "conf_DataIdF" ) + "";  // config not required


//// == Data Retrieving / ワークフローデータの参照 ==
if( engine.findDataByNumber( dataIdA ) === null ){
  throw new Error( "\n AutomatedTask UnexpectedDatetimeError:" +
                   " Datetime {A} is null \n" );
}
if( engine.findDataByNumber( dataIdB ) === null ){
  throw new Error( "\n AutomatedTask UnexpectedDatetimeError:" +
                   " Datetime {B} is null \n" );
}
let strDateA = engine.findDataByNumber( dataIdA ) + ""; // "2020-04-30 12:59"
let strDateB = engine.findDataByNumber( dataIdB ) + ""; // "2020-04-30"

const regBpmsY  = /^\d{4}$/;       // "2020"
const regBpmsYM = /^\d{4}-\d{2}$/; // "2020-04"
const regBpmsMD = /^\d{2}-\d{2}$/; // "04-30"
engine.log( " AutomatedTask String A: " + strDateA );
if( regBpmsY.test( strDateA ) ){
  strDateA = strDateA + "-01-01";
  engine.log( " AutomatedTask String A (as): " + strDateA );
}
if( regBpmsYM.test( strDateA ) ){
  strDateA = strDateA + "-01";
  engine.log( " AutomatedTask String A (as): " + strDateA );
}
if( regBpmsMD.test( strDateA ) ){
  let  now = new Date();
  strDateA = now.getFullYear() + "-" + strDateA;
  engine.log( " AutomatedTask String A (as): " + strDateA );
}
engine.log( " AutomatedTask String B: " + strDateB );
if( regBpmsY.test( strDateB ) ){
  strDateB = strDateB + "-01-01";
  engine.log( " AutomatedTask String B (as): " + strDateB );
}
if( regBpmsYM.test( strDateB ) ){
  strDateB = strDateB + "-01";
  engine.log( " AutomatedTask String B (as): " + strDateB );
}
if( regBpmsMD.test( strDateB ) ){
  let  now = new Date();
  strDateB = now.getFullYear() + "-" + strDateB;
  engine.log( " AutomatedTask String B (as): " + strDateB );
}


//// == Calculating / 演算 ==
const dateA = toJsDate( strDateA ); // ECMA/JavaScript Date
const dateB = toJsDate( strDateB );
const numMilliEpochA = dateA.getTime();
const numMilliEpochB = dateB.getTime();
const numMilliDuration = numMilliEpochB - numMilliEpochA;


//// == Data Updating / ワークフローデータへの代入 ==
if( dataIdC !== "" ){
  engine.setDataByNumber( dataIdC,
    new java.math.BigDecimal( numMilliDuration /1000 /60 /60 /24 )
  );
}
if( dataIdD !== "" ){
  engine.setDataByNumber( dataIdD,
    new java.math.BigDecimal( numMilliDuration /1000 /60 /60 )
  );
}
if( dataIdE !== "" ){
  engine.setDataByNumber( dataIdE,
    new java.math.BigDecimal( numMilliDuration /1000 /60 )
  );
}
if( dataIdF !== "" ){
  let hour = parseInt( numMilliDuration /1000 /60 /60 );
  let min  = Math.abs(parseInt(( numMilliDuration /1000 /60 ) %60));
  if( min < 10 ){ min = "0" + min; }
  engine.setDataByNumber( dataIdF, hour + ":" + min );
}


} //////// END "main()" /////////////////////////////////////////////////////////////////


function toJsDate( bpmsDateOrDatetimeStr ){
  // BPMS Date:     "2020-04-01"  (subtype "Y/M" "M/D" "Y", not supported)
  // BPMS Datetime: "2020-04-01 23:59"
  let year       = 0;
  let monthIndex = 0;
  let day        = 0;
  let hours      = 0;
  let minutes    = 0;

  //  The ECMA/JavaScript Date object has a large number of methods.
  // "Date.parse" is danger (strongly discouraged)
  // - new Date("2014-11-10") // Mon Nov 10 2014 09:00:00 GMT+0900 (JST)
  // - new Date(2014, 10, 10) // Mon Nov 10 2014 00:00:00 GMT+0900 (JST)
  let arrDatetime = bpmsDateOrDatetimeStr.split(" ");
  if( arrDatetime.length === 1 ){
    let arrDateParts = arrDatetime[0].split("-");
    year       = parseInt(arrDateParts[0], 10);
    monthIndex = parseInt(arrDateParts[1], 10) - 1;
    day        = parseInt(arrDateParts[2], 10);
  }
  if( arrDatetime.length === 2 ){
    let arrDateParts = arrDatetime[0].split("-");
    let arrTimeParts = arrDatetime[1].split(":");
    year       = parseInt(arrDateParts[0], 10);
    monthIndex = parseInt(arrDateParts[1], 10) - 1;
    day        = parseInt(arrDateParts[2], 10);
    hours      = parseInt(arrTimeParts[0], 10);
    minutes    = parseInt(arrTimeParts[1], 10);
  }
  return new Date( year, monthIndex, day, hours, minutes );
}

Download

Capture

Calculates the duration between datetime A and B to output as numerical value (days), numerical value (hours), numerical value (minutes), or string value (h:mm). If B is the past time, a minus sign will be added. Date type also available.

Notes

  1. The number of decimal places for Days and Hours depends on the numeric definition.
  2. “00:00” is applied when Date type data is compared.
  3. If Date subtype “YM”, “-01” is added.
  4. If Date subtype “Y”, “-01-01” is added.
  5. If Date subtype “MD”, ‘YYYY-‘ as of processing is added.

See also

3 thoughts on “Two Datetimes, Calculate Duration”

  1. Pingback: Days Calculator – Questetra Support

  2. Pingback: Minutes Calculator – Questetra Support

  3. Pingback: Accumulated Hours Calculator – Questetra Support

Leave a Reply

This site uses Akismet to reduce spam. Learn how your comment data is processed.

%d bloggers like this: