Two Dates, Calculate Business Days

Two Dates, Calculate Business Days
Calculates Business Day Count between datetime A and B to output as numerical value (days). It is necessary to set holidays in advance. It is also possible to add company-original holidays.
Configs
  • A: Select DATE DATA *
  • B: Select DATE DATA *
  • C: Holiday Master File Name *
  • D: Share Kind Of Holiday Master File (ON: Shared)
  • E: Set Days of Week to be Closed (eg “0,Sun” )#{EL}
  • F: Select DECIMAL DATA that stores Calced Date (update) *
Script (click to open)

main();
function main(){
//////// START "main()" /////////////////////////////////////////////////////////////////
//// == Config Retrieving / 工程コンフィグの参照 ==
const numDataIdA = configs.get("conf_DataIdA");
const numDataIdB = configs.get("conf_DataIdB");
const holidayMasterFileName = configs.get("conf_HolidayMasterFileName");
const strIsShare = configs.get("conf_IsShareHolidayMaster");
const closedDaysConfigs = configs.get("conf_DataIdE");
const numDataIdF = configs.get("conf_DataIdF");

//// == Data Retrieving / ワークフローデータの参照 ==
let startDate = engine.findDataByNumber( numDataIdA );
let endDate = engine.findDataByNumber( numDataIdB );
let strEndDate = "";
//// == Calculating / 演算 ==
if ( startDate === null){
engine.log("Start Date is null. Business Day Count is zero.");
engine.setDataByNumber( numDataIdF, new java.math.BigDecimal( 0 ) );
return;
}
if ( endDate === null ){
engine.log("End Date is null. Force Set Today to End Date.");
let now = new Date();
endDate = java.sql.Date.valueOf(now.getFullYear() + "-" + (now.getMonth()+1).toString().padStart(2, '0') + "-" + now.getDate().toString().padStart(2, '0'));
engine.setDataByNumber( numDataIdB , endDate);
now.setDate(now.getDate() + 1 );
strEndDate = now.getFullYear() + "-" + (now.getMonth()+1).toString().padStart(2, '0') + "-" + now.getDate().toString().padStart(2, '0');
}else{
strEndDate = endDate.addDays(1) + "";
}
engine.log("strEndDate: " + strEndDate);
const milliSecStartDate = toJsDate( startDate + "").getTime();
const milliSecEndDate = toJsDate( strEndDate ).getTime(); // include last day
const milliSecDuration = milliSecEndDate - milliSecStartDate;

if ( milliSecStartDate >= milliSecEndDate ){
engine.log("Start Date >= End Date. Business Day Count is zero.");
engine.setDataByNumber( numDataIdF, new java.math.BigDecimal( 0 ) );
return;
}

let excludeCount = 0;
let closedDays = new Array();
if (closedDaysConfigs !== null){
closedDays = closedDaysConfigs.split("\n");
}
engine.log("closedDays lenght: " + closedDays.length);
const allDurationDaysCount = milliSecDuration /1000 /60 /60 /24 ;
engine.log("All Duration Days: " + allDurationDaysCount);

let isShare = true;
if (strIsShare === "false"){
isShare = false;
}
// Holiday Master Check
const holidayConfigList = itemDao.findAll( holidayMasterFileName , isShare);
for (let i=0; i < holidayConfigList.size(); i++){
let config = holidayConfigList.get(i);
let dateObjHoriday = toJsDate( config.getValue() );
let milliSecHoridayDate = toJsDate( config.getValue() ).getTime();
let horidayName = config.getDisplay();
if (( milliSecStartDate <= milliSecHoridayDate )&&( milliSecEndDate >= milliSecHoridayDate )){
engine.log("Exclude Holiday: " + config.getValue() + " " + horidayName);
excludeCount++;
// Avoid Duplication (Holiday and Weekly Closed Day)
for (let j=0; j < closedDays.length; j++){
let closedDay = closedDays[j].split(",");
if (closedDay[0] === (dateObjHoriday.getDay() + "")){
engine.log(config.getValue() + " " + horidayName + " " + closedDay[1]);
excludeCount--;
break;
}
}
}
}
// "Days of Week to be Closed" Check
for (let i=0; i < allDurationDaysCount; i++){
let dateObjTargetDate = toJsDate( startDate.addDays(i) + "" );
for (let j=0; j < closedDays.length; j++){
let closedDay = closedDays[j].split(",");
if (closedDay[0] === (dateObjTargetDate.getDay() + "")){
engine.log("Exclude Close Days: " + (startDate.addDays(i) + ""));
excludeCount++;
break;
}
}
}
//// == Data Updating / ワークフローデータへの代入 ==
engine.log("Exclude Count: " + excludeCount);
engine.log("Business Days Count: " + (allDurationDaysCount - excludeCount));
engine.setDataByNumber( numDataIdF , new java.math.BigDecimal(allDurationDaysCount - excludeCount) );
} //////// 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

2022-09-09 (C) Questetra, Inc. (MIT License)
https://support.questetra.com/addons/services/two-dates-calculate-duration-exclude-close-days-202209/
The Addon-import feature is available with Professional edition.
Freely modifiable JavaScript (ECMAScript) code. No warranty of any kind.

Notes

  • Period of Calculating Business Days
    • Between “A:” Data Item (Date Type) and “B:” Data Item (Date Type). Include days (“A:”,”B:” day).
  • “D: Share Kind Of Holiday Master File (ON: Shared)”
    • “C:” Master file of Select type Data Item [ON] App-shared Add-on file , [OFF] Add-on file
  • “A:” Data Item is Null
    • Business Days is “0”.
  • Holiday and Closed Day are the same
    • Count as one day.

Capture

Appendix

  • “C:” Holiday Master File (example: Japanese Holiday)
<items>
<item value="2022-01-01" display="元日" />
<item value="2022-01-10" display="成人の日" />
<item value="2022-02-11" display="建国記念の日" />
<item value="2022-02-23" display="天皇誕生日" />
<item value="2022-03-21" display="春分の日" />
<item value="2022-04-29" display="昭和の日" />
<item value="2022-05-03" display="憲法記念日" />
<item value="2022-05-04" display="みどりの日" />
<item value="2022-05-05" display="こどもの日" />
<item value="2022-07-18" display="海の日" />
<item value="2022-08-11" display="山の日" />
<item value="2022-09-19" display="敬老の日" />
<item value="2022-09-23" display="秋分の日" />
<item value="2022-10-10" display="スポーツの日" />
<item value="2022-11-03" display="文化の日" />
<item value="2022-11-23" display="勤労感謝の日" />
<item value="2023-01-01" display="元日" />
<item value="2023-01-02" display="休日" />
<item value="2023-01-09" display="成人の日" />
<item value="2023-02-11" display="建国記念の日" />
<item value="2023-02-23" display="天皇誕生日" />
<item value="2023-03-21" display="春分の日" />
<item value="2023-04-29" display="昭和の日" />
<item value="2023-05-03" display="憲法記念日" />
<item value="2023-05-04" display="みどりの日" />
<item value="2023-05-05" display="こどもの日" />
<item value="2023-07-17" display="海の日" />
<item value="2023-08-11" display="山の日" />
<item value="2023-09-18" display="敬老の日" />
<item value="2023-09-23" display="秋分の日" />
<item value="2023-10-09" display="スポーツの日" />
<item value="2023-11-03" display="文化の日" />
<item value="2023-11-23" display="勤労感謝の日" />
</items>

See also

Leave a Reply

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

Scroll to Top

Discover more from Questetra Support

Subscribe now to keep reading and get access to the full archive.

Continue reading