Status implementation
This commit is contained in:
1 parent
b0bfc632e4
commit
4aaeb1dd27
20 files changed
+357
-65
No files matched your search
+12
-5
@@ -37,18 +37,25 @@ exports.newDebugLog = function newDebugLog() {
|
||||
}
|
||||
}
|
||||
|
||||
function newInternalLoop(pBot, pProcess, date) {
|
||||
function newInternalLoop(pBot, pProcess, date, percentage) {
|
||||
if (percentage === undefined) {
|
||||
percentage = ""
|
||||
} else {
|
||||
percentage = percentage.toFixed(0) + "%"
|
||||
}
|
||||
|
||||
if (date === undefined) { date = thisObject.bot.processDatetime }
|
||||
date = date.getUTCFullYear() + '-' + strPad(date.getUTCMonth() + 1, 2, "0") + '-' + strPad(date.getUTCDate(), 2, "0");
|
||||
|
||||
console.log(new Date().toISOString() + " " + strPad(pBot, 20) + " " + strPad(pProcess, 30) + " " + strPad(thisObject.bot.exchange, 20) + " " + strPad(thisObject.bot.market.baseAsset + '/' + thisObject.bot.market.quotedAsset, 10)
|
||||
+ " Entered into Internal Loop # " + strPad(internalLoopCounter + 1, 8) + " " + strPad(date.toISOString(), 30))
|
||||
console.log(new Date().toISOString() + " " + strPad(thisObject.bot.exchange, 20) + " " + strPad(thisObject.bot.market.baseAsset + '/' + thisObject.bot.market.quotedAsset, 10) + " " + strPad(pBot, 20) + " " + strPad(pProcess, 30)
|
||||
+ " Internal Loop # " + strPad(internalLoopCounter + 1, 8) + " " + strPad(date, 30) + " " + strPad(percentage, 10))
|
||||
|
||||
persist();
|
||||
|
||||
function strPad(str, max) {
|
||||
function strPad(str, max, fill) {
|
||||
if (fill === undefined) {fill = " "}
|
||||
str = str.toString();
|
||||
return str.length < max ? strPad(" " + str, max) : str;
|
||||
return str.length < max ? strPad(fill + str, max) : str;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -51,7 +51,7 @@ exports.newFileStorage = function newFileStorage(logger) {
|
||||
|
||||
function onFileRead(err, text) {
|
||||
let retryTimeToUse = FAST_RETRY_TIME_IN_MILISECONDS
|
||||
if (currentRetryGetTextFile < MAX_RETRY - 3) {
|
||||
if (currentRetryGetTextFile > MAX_RETRY - 2) {
|
||||
retryTimeToUse = SLOW_RETRY_TIME_IN_MILISECONDS
|
||||
}
|
||||
if (err) {
|
||||
@@ -96,6 +96,7 @@ exports.newFileStorage = function newFileStorage(logger) {
|
||||
}
|
||||
|
||||
function retry() {
|
||||
//console.log(new Date(), ' Retry #: ' + currentRetryGetTextFile, fileLocation )
|
||||
if (currentRetryGetTextFile < MAX_RETRY) {
|
||||
currentRetryGetTextFile++
|
||||
logger.write(MODULE_NAME, '[WARN] FileStorage -> getTextFile -> retry -> Will try to read the file again -> Retry #: ' + currentRetryGetTextFile)
|
||||
@@ -150,7 +151,7 @@ exports.newFileStorage = function newFileStorage(logger) {
|
||||
|
||||
function onFileWritenn(err) {
|
||||
let retryTimeToUse = FAST_RETRY_TIME_IN_MILISECONDS
|
||||
if (currentRetryWriteTextFile < MAX_RETRY - 3) {
|
||||
if (currentRetryWriteTextFile > MAX_RETRY - 2) {
|
||||
retryTimeToUse = SLOW_RETRY_TIME_IN_MILISECONDS
|
||||
}
|
||||
if (err) {
|
||||
|
||||
@@ -145,8 +145,8 @@
|
||||
|
||||
/* High level log entry */
|
||||
|
||||
console.log(new Date().toISOString() + " " + pad(bot.codeName, 20) + " " + pad(bot.process, 30) + " " + pad(bot.exchange, 20) + " " + pad(bot.market.baseAsset + '/' + bot.market.quotedAsset, 10)
|
||||
+ " Entered into Main Loop # " + pad(Number(bot.loopCounter), 8));
|
||||
console.log(new Date().toISOString() + " " + pad(bot.exchange, 20) + " " + pad(bot.market.baseAsset + '/' + bot.market.quotedAsset, 10) + " " + pad(bot.codeName, 20) + " " + pad(bot.process, 30)
|
||||
+ " Main Loop # " + pad(Number(bot.loopCounter), 8))
|
||||
|
||||
/* We will prepare first the infraestructure needed for the bot to run. There are 3 modules we need to sucessfullly initialize first. */
|
||||
|
||||
@@ -964,6 +964,7 @@
|
||||
logger.persist();
|
||||
}
|
||||
|
||||
processStopped()
|
||||
callBackFunction(global.DEFAULT_OK_RESPONSE);
|
||||
return;
|
||||
|
||||
@@ -982,6 +983,7 @@
|
||||
checkLoopHealthHandle = setTimeout(checkLoopHealth, processConfig.deadWaitTime, bot.loopCounter);
|
||||
}
|
||||
nextLoopTimeoutHandle = setTimeout(loop, processConfig.normalWaitTime);
|
||||
processHeartBeat(undefined, undefined, "Waiting " + processConfig.normalWaitTime / 1000 + " seconds for next execution.")
|
||||
if(global.WRITE_LOGS_TO_FILES === 'true'){
|
||||
logger.persist();
|
||||
}
|
||||
@@ -993,18 +995,21 @@
|
||||
checkLoopHealthHandle = setTimeout(checkLoopHealth, processConfig.deadWaitTime, bot.loopCounter);
|
||||
}
|
||||
nextLoopTimeoutHandle = setTimeout(loop, processConfig.retryWaitTime);
|
||||
processHeartBeat(undefined, undefined, "Trying to recover from some problem. Waiting " + processConfig.retryWaitTime / 1000 + " seconds for next execution.")
|
||||
logger.persist();
|
||||
}
|
||||
break;
|
||||
case 'Sleep': {
|
||||
if (FULL_LOG === true) { logger.write(MODULE_NAME, "[INFO] run -> loop -> loopControl -> Restarting Loop in " + (processConfig.sleepWaitTime / 60000) + " minutes."); }
|
||||
nextLoopTimeoutHandle = setTimeout(loop, processConfig.sleepWaitTime);
|
||||
processHeartBeat(undefined, undefined, "Waiting " + processConfig.sleepWaitTime / 60000 + " minutes for next execution.")
|
||||
logger.persist();
|
||||
}
|
||||
break;
|
||||
case 'Coma': {
|
||||
if (FULL_LOG === true) { logger.write(MODULE_NAME, "[INFO] run -> loop -> loopControl -> Restarting Loop in " + (processConfig.comaWaitTime / 3600000) + " hours."); }
|
||||
nextLoopTimeoutHandle = setTimeout(loop, processConfig.comaWaitTime);
|
||||
processHeartBeat(undefined, undefined, "Waiting " + processConfig.comaWaitTime / 3600000 + " hours for next execution.")
|
||||
logger.persist();
|
||||
}
|
||||
break;
|
||||
@@ -1076,10 +1081,12 @@
|
||||
}
|
||||
}
|
||||
|
||||
function processHeartBeat(processingDate) {
|
||||
function processHeartBeat(processingDate, percentage, status) {
|
||||
let event = {
|
||||
seconds: (new Date()).getSeconds(),
|
||||
processingDate: processingDate
|
||||
processingDate: processingDate,
|
||||
percentage: percentage,
|
||||
status: status
|
||||
}
|
||||
global.SYSTEM_EVENT_HANDLER.raiseEvent(bot.processKey, 'Heartbeat', event)
|
||||
}
|
||||
|
||||
@@ -307,6 +307,8 @@
|
||||
let botNeverRan = true;
|
||||
|
||||
bot.multiPeriodDailyProcessDatetime = new Date(contextVariables.lastFile.valueOf() - ONE_DAY_IN_MILISECONDS); // Go back one day to start well when we advance time at the begining of the loop.
|
||||
let fromDate = new Date(bot.multiPeriodDailyProcessDatetime.valueOf())
|
||||
let lastDate = new Date()
|
||||
|
||||
advanceTime();
|
||||
|
||||
@@ -334,6 +336,16 @@
|
||||
|
||||
}
|
||||
|
||||
/* Telling the world we are alive and doing well */
|
||||
let currentDateString = bot.multiPeriodDailyProcessDatetime.getUTCFullYear() + '-' + utilities.pad(bot.multiPeriodDailyProcessDatetime.getUTCMonth() + 1, 2) + '-' + utilities.pad(bot.multiPeriodDailyProcessDatetime.getUTCDate(), 2);
|
||||
let currentDate = new Date(bot.multiPeriodDailyProcessDatetime)
|
||||
let percentage = global.getPercentage(fromDate, currentDate, lastDate)
|
||||
bot.processHeartBeat(currentDateString, percentage)
|
||||
|
||||
if (global.areEqualDates(currentDate, new Date()) === false) {
|
||||
logger.newInternalLoop(bot.codeName, bot.process, currentDate, percentage);
|
||||
}
|
||||
|
||||
checkStopTaskGracefully();
|
||||
|
||||
} catch (err) {
|
||||
@@ -371,10 +383,6 @@
|
||||
|
||||
if (FULL_LOG === true) { logger.write(MODULE_NAME, "[INFO] start -> processTimeFrames -> periodsLoop -> Entering function."); }
|
||||
|
||||
/* Telling the world we are alive and doing well */
|
||||
let processingDate = bot.multiPeriodDailyProcessDatetime.getUTCFullYear() + '-' + utilities.pad(bot.multiPeriodDailyProcessDatetime.getUTCMonth() + 1, 2) + '-' + utilities.pad(bot.multiPeriodDailyProcessDatetime.getUTCDate(), 2);
|
||||
bot.processHeartBeat(processingDate)
|
||||
|
||||
/*
|
||||
|
||||
We will iterate through all posible periods.
|
||||
@@ -808,7 +816,6 @@
|
||||
|
||||
bot.hasTheBotJustStarted = false;
|
||||
|
||||
logger.newInternalLoop(bot.codeName, bot.process, bot.multiPeriodDailyProcessDatetime);
|
||||
}
|
||||
catch (err) {
|
||||
logger.write(MODULE_NAME, "[ERROR] start -> writeStatusReport -> err = "+ err.stack);
|
||||
|
||||
@@ -338,7 +338,15 @@
|
||||
thisReport.file.lastExecution = bot.processDatetime;
|
||||
thisReport.save(callBack);
|
||||
|
||||
logger.newInternalLoop(bot.codeName, bot.process, bot.processDatetime);
|
||||
if (global.areEqualDates(bot.processDatetime, new Date()) === false) {
|
||||
logger.newInternalLoop(bot.codeName, bot.process, bot.processDatetime);
|
||||
}
|
||||
|
||||
/* Telling the world we are alive and doing well */
|
||||
let currentDateString = bot.processDatetime.getUTCFullYear() + '-' + utilities.pad(bot.processDatetime.getUTCMonth() + 1, 2) + '-' + utilities.pad(bot.processDatetime.getUTCDate(), 2);
|
||||
let currentDate = new Date(bot.processDatetime)
|
||||
let lastDate = new Date()
|
||||
bot.processHeartBeat(currentDateString, global.getPercentage(currentDate, currentDate, lastDate))
|
||||
}
|
||||
catch (err) {
|
||||
logger.write(MODULE_NAME, "[ERROR] start -> writeStatusReport -> err = "+ err.stack);
|
||||
|
||||
@@ -83,6 +83,8 @@
|
||||
|
||||
global.SYSTEM_EVENT_HANDLER.listenToEvent(key, 'Process Execution Finished', undefined, callerId, responseCallBack, eventsCallBack)
|
||||
|
||||
bot.processHeartBeat(undefined, undefined, "Waiting for " + processThisDependsOn.parentNode.parentNode.name + "->" + processThisDependsOn.parentNode.code.codeName + "->" + processThisDependsOn.code.codeName)
|
||||
|
||||
function responseCallBack(message) {
|
||||
if (message.result !== global.DEFAULT_OK_RESPONSE.result) {
|
||||
logger.write(MODULE_NAME, "[ERROR] start -> responseCallBack -> message = " + JSON.stringify(message))
|
||||
@@ -110,6 +112,8 @@
|
||||
global.SYSTEM_EVENT_HANDLER.createEventHandler(currentProcessKey, 'Process Execution Started')
|
||||
global.SYSTEM_EVENT_HANDLER.raiseEvent(currentProcessKey, 'Process Execution Started', event)
|
||||
|
||||
bot.processHeartBeat(undefined, undefined,"Running...")
|
||||
|
||||
if (global.LOG_CONTROL[MODULE_NAME].logInfo === true) { logger.write(MODULE_NAME, "[INFO] start -> eventsCallBack -> " + currentProcessKey + " Process Execution Started because " + key + " Finished."); }
|
||||
}
|
||||
|
||||
|
||||
@@ -113,7 +113,7 @@
|
||||
function loop() {
|
||||
|
||||
try {
|
||||
|
||||
processHeartBeat(undefined, undefined, "Running...")
|
||||
function pad(str, max) {
|
||||
str = str.toString();
|
||||
return str.length < max ? pad(" " + str, max) : str;
|
||||
@@ -148,8 +148,8 @@
|
||||
|
||||
/* High level log entry */
|
||||
|
||||
console.log(new Date().toISOString() + " " + pad(bot.codeName, 20) + " " + pad(bot.process, 30) + " " + pad(bot.exchange, 20) + " " + pad(bot.market.baseAsset + '/' + bot.market.quotedAsset, 10)
|
||||
+ " Entered into Main Loop # " + pad(Number(bot.loopCounter), 8) )
|
||||
console.log(new Date().toISOString() + " " + pad(bot.exchange, 20) + " " + pad(bot.market.baseAsset + '/' + bot.market.quotedAsset, 10) + " " + pad(bot.codeName, 20) + " " + pad(bot.process, 30)
|
||||
+ " Main Loop # " + pad(Number(bot.loopCounter), 8) )
|
||||
|
||||
/* We will prepare first the infraestructure needed for the bot to run. There are 4 modules we need to sucessfullly initialize first. */
|
||||
|
||||
@@ -655,9 +655,6 @@
|
||||
if (FULL_LOG === true) { logger.write(MODULE_NAME, "[INFO] run -> loop -> loopControl -> nextWaitTime = " + nextWaitTime); }
|
||||
|
||||
/* We show we reached the end of the loop. */
|
||||
|
||||
processHeartBeat()
|
||||
|
||||
/* Here we check if we must stop the loop gracefully. */
|
||||
|
||||
shallWeStop(onStop, onContinue);
|
||||
@@ -676,6 +673,7 @@
|
||||
clearTimeout(nextLoopTimeoutHandle);
|
||||
clearTimeout(checkLoopHealthHandle);
|
||||
bot.enableCheckLoopHealth = false;
|
||||
processStopped()
|
||||
callBackFunction(global.DEFAULT_OK_RESPONSE);
|
||||
return;
|
||||
|
||||
@@ -689,24 +687,14 @@
|
||||
|
||||
switch (nextWaitTime) {
|
||||
case 'Normal': {
|
||||
if (bot.runAtFixedInterval === true) {
|
||||
if (FULL_LOG === true) { logger.write(MODULE_NAME, "[INFO] run -> loop -> loopControl -> Fixed Interval Normal exit point reached."); }
|
||||
if (processConfig.deadWaitTime > 0) {
|
||||
checkLoopHealthHandle = setTimeout(checkLoopHealth, processConfig.deadWaitTime, bot.loopCounter);
|
||||
}
|
||||
if(global.WRITE_LOGS_TO_FILES === 'true'){
|
||||
logger.persist();
|
||||
}
|
||||
return;
|
||||
} else {
|
||||
if (FULL_LOG === true) { logger.write(MODULE_NAME, "[INFO] run -> loop -> loopControl -> Restarting Loop in " + (processConfig.normalWaitTime / 1000) + " seconds."); }
|
||||
if (processConfig.deadWaitTime > 0) {
|
||||
checkLoopHealthHandle = setTimeout(checkLoopHealth, processConfig.deadWaitTime, bot.loopCounter);
|
||||
}
|
||||
nextLoopTimeoutHandle = setTimeout(loop, processConfig.normalWaitTime);
|
||||
if(global.WRITE_LOGS_TO_FILES === 'true'){
|
||||
logger.persist();
|
||||
}
|
||||
if (FULL_LOG === true) { logger.write(MODULE_NAME, "[INFO] run -> loop -> loopControl -> Restarting Loop in " + (processConfig.normalWaitTime / 1000) + " seconds."); }
|
||||
if (processConfig.deadWaitTime > 0) {
|
||||
checkLoopHealthHandle = setTimeout(checkLoopHealth, processConfig.deadWaitTime, bot.loopCounter);
|
||||
}
|
||||
nextLoopTimeoutHandle = setTimeout(loop, processConfig.normalWaitTime);
|
||||
processHeartBeat(undefined, undefined, "Waiting " + processConfig.normalWaitTime / 1000 + " seconds for next execution.")
|
||||
if(global.WRITE_LOGS_TO_FILES === 'true'){
|
||||
logger.persist();
|
||||
}
|
||||
}
|
||||
break;
|
||||
@@ -716,6 +704,7 @@
|
||||
checkLoopHealthHandle = setTimeout(checkLoopHealth, processConfig.retryWaitTime * 5, bot.loopCounter);
|
||||
}
|
||||
nextLoopTimeoutHandle = setTimeout(loop, processConfig.retryWaitTime);
|
||||
processHeartBeat(undefined, undefined, "Trying to recover from some problem. Waiting " + processConfig.retryWaitTime / 1000 + " seconds for next execution.")
|
||||
logger.persist();
|
||||
}
|
||||
break;
|
||||
@@ -727,6 +716,7 @@
|
||||
} else {
|
||||
if (FULL_LOG === true) { logger.write(MODULE_NAME, "[INFO] run -> loop -> loopControl -> Restarting Loop in " + (processConfig.sleepWaitTime / 60000) + " minutes."); }
|
||||
nextLoopTimeoutHandle = setTimeout(loop, processConfig.sleepWaitTime);
|
||||
processHeartBeat(undefined, undefined, "Waiting " + processConfig.sleepWaitTime / 60000 + " minutes for next execution.")
|
||||
logger.persist();
|
||||
}
|
||||
}
|
||||
@@ -739,6 +729,7 @@
|
||||
} else {
|
||||
if (FULL_LOG === true) { logger.write(MODULE_NAME, "[INFO] run -> loop -> loopControl -> Restarting Loop in " + (processConfig.comaWaitTime / 3600000) + " hours."); }
|
||||
nextLoopTimeoutHandle = setTimeout(loop, processConfig.comaWaitTime);
|
||||
processHeartBeat(undefined, undefined, "Waiting " + processConfig.comaWaitTime / 3600000 + " hours for next execution.")
|
||||
logger.persist();
|
||||
}
|
||||
}
|
||||
@@ -812,10 +803,12 @@
|
||||
}
|
||||
}
|
||||
|
||||
function processHeartBeat(processingDate) {
|
||||
function processHeartBeat(processingDate, percentage, status) {
|
||||
let event = {
|
||||
seconds: (new Date()).getSeconds(),
|
||||
processingDate: processingDate
|
||||
processingDate: processingDate,
|
||||
percentage: percentage,
|
||||
status: status
|
||||
}
|
||||
global.SYSTEM_EVENT_HANDLER.raiseEvent(bot.processKey, 'Heartbeat', event)
|
||||
}
|
||||
|
||||
@@ -157,8 +157,8 @@
|
||||
|
||||
/* High level log entry */
|
||||
|
||||
console.log(new Date().toISOString() + " " + pad(bot.codeName, 20) + " " + pad(bot.process, 30) + " " + pad(bot.exchange, 20) + " " + pad(bot.market.baseAsset + '/' + bot.market.quotedAsset, 10)
|
||||
+ " Entered into Main Loop # " + pad(Number(bot.loopCounter), 8) + " " + bot.sessionKey )
|
||||
console.log(new Date().toISOString() + " " + pad(bot.exchange, 20) + " " + pad(bot.market.baseAsset + '/' + bot.market.quotedAsset, 10) + " " + pad(bot.codeName, 20) + " " + pad(bot.process, 30)
|
||||
+ " Main Loop # " + pad(Number(bot.loopCounter), 8) + " " + bot.sessionKey)
|
||||
|
||||
/* Checking if we need to need to emit any event */
|
||||
|
||||
@@ -880,6 +880,7 @@
|
||||
}
|
||||
|
||||
global.SYSTEM_EVENT_HANDLER.raiseEvent(bot.sessionKey, 'Stopped')
|
||||
processStopped()
|
||||
callBackFunction(global.DEFAULT_OK_RESPONSE);
|
||||
return;
|
||||
|
||||
@@ -905,6 +906,7 @@
|
||||
checkLoopHealthHandle = setTimeout(checkLoopHealth, processConfig.deadWaitTime, bot.loopCounter);
|
||||
}
|
||||
nextLoopTimeoutHandle = setTimeout(loop, waitTime);
|
||||
processHeartBeat(undefined, undefined, "Waiting " + processConfig.waitTime / 1000 + " seconds for next execution.")
|
||||
if (global.WRITE_LOGS_TO_FILES === 'true') {
|
||||
logger.persist();
|
||||
}
|
||||
@@ -916,18 +918,21 @@
|
||||
checkLoopHealthHandle = setTimeout(checkLoopHealth, processConfig.deadWaitTime, bot.loopCounter);
|
||||
}
|
||||
nextLoopTimeoutHandle = setTimeout(loop, processConfig.retryWaitTime);
|
||||
processHeartBeat(undefined, undefined, "Trying to recover from some problem. Waiting " + processConfig.retryWaitTime / 1000 + " seconds for next execution.")
|
||||
logger.persist();
|
||||
}
|
||||
break;
|
||||
case 'Sleep': {
|
||||
if (FULL_LOG === true) { logger.write(MODULE_NAME, "[INFO] run -> loop -> loopControl -> Restarting Loop in " + (processConfig.sleepWaitTime / 60000) + " minutes."); }
|
||||
nextLoopTimeoutHandle = setTimeout(loop, processConfig.sleepWaitTime);
|
||||
processHeartBeat(undefined, undefined, "Waiting " + processConfig.sleepWaitTime / 60000 + " minutes for next execution.")
|
||||
logger.persist();
|
||||
}
|
||||
break;
|
||||
case 'Coma': {
|
||||
if (FULL_LOG === true) { logger.write(MODULE_NAME, "[INFO] run -> loop -> loopControl -> Restarting Loop in " + (processConfig.comaWaitTime / 3600000) + " hours."); }
|
||||
nextLoopTimeoutHandle = setTimeout(loop, processConfig.comaWaitTime);
|
||||
processHeartBeat(undefined, undefined, "Waiting " + processConfig.comaWaitTime / 3600000 + " hours for next execution.")
|
||||
logger.persist();
|
||||
}
|
||||
break;
|
||||
@@ -1000,10 +1005,12 @@
|
||||
}
|
||||
}
|
||||
|
||||
function processHeartBeat(processingDate) {
|
||||
function processHeartBeat(processingDate, percentage, status) {
|
||||
let event = {
|
||||
seconds: (new Date()).getSeconds(),
|
||||
processingDate: processingDate
|
||||
processingDate: processingDate,
|
||||
percentage: percentage,
|
||||
status: status
|
||||
}
|
||||
global.SYSTEM_EVENT_HANDLER.raiseEvent(bot.processKey, 'Heartbeat', event)
|
||||
}
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
const LOG_FILE_CONTENT = false;
|
||||
|
||||
const MODULE_NAME = "Trading Simulation -> " + bot.SESSION.name;
|
||||
const ONE_DAY_IN_MILISECONDS = 24 * 60 * 60 * 1000;
|
||||
|
||||
const GMT_SECONDS = ':00.000 GMT+0000';
|
||||
|
||||
let thisObject = {
|
||||
|
||||
@@ -25,6 +25,8 @@ global.CUSTOM_FAIL_RESPONSE = {
|
||||
message: "Custom Message"
|
||||
};
|
||||
|
||||
const ONE_DAY_IN_MILISECONDS = 24 * 60 * 60 * 1000;
|
||||
|
||||
/* Process Events */
|
||||
|
||||
process.on('uncaughtException', function (err) {
|
||||
@@ -260,3 +262,25 @@ function startRoot(processIndex) {
|
||||
}
|
||||
}
|
||||
|
||||
global.getPercentage = function (fromDate, currentDate, lastDate) {
|
||||
let fromDays = Math.trunc(fromDate.valueOf() / ONE_DAY_IN_MILISECONDS)
|
||||
let currentDays = Math.trunc(currentDate.valueOf() / ONE_DAY_IN_MILISECONDS)
|
||||
let lastDays = Math.trunc(lastDate.valueOf() / ONE_DAY_IN_MILISECONDS)
|
||||
let percentage = (currentDays - fromDays) * 100 / (lastDays - fromDays)
|
||||
if ((lastDays - fromDays) === 0) {
|
||||
percentage = 100
|
||||
}
|
||||
return percentage
|
||||
}
|
||||
|
||||
global.areEqualDates = function (date1, date2) {
|
||||
let day1Days = Math.trunc(date1.valueOf() / ONE_DAY_IN_MILISECONDS)
|
||||
let day2Days = Math.trunc(date2.valueOf() / ONE_DAY_IN_MILISECONDS)
|
||||
|
||||
if (day1Days === day2Days) {
|
||||
return true
|
||||
} else {
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
Reference in new issue
Block a user