Files
DocumentServer-v-9.2.0/sdkjs/cell/model/FormulaObjects/dateandtimeFunctions.js
T
Yajbir Singh f1b860b25c
check / markdownlint (push) Has been cancelled
check / spellchecker (push) Has been cancelled
updated
2025-12-11 19:03:17 +05:30

2452 lines
73 KiB
JavaScript

/*
* (c) Copyright Ascensio System SIA 2010-2024
*
* This program is a free software product. You can redistribute it and/or
* modify it under the terms of the GNU Affero General Public License (AGPL)
* version 3 as published by the Free Software Foundation. In accordance with
* Section 7(a) of the GNU AGPL its Section 15 shall be amended to the effect
* that Ascensio System SIA expressly excludes the warranty of non-infringement
* of any third-party rights.
*
* This program is distributed WITHOUT ANY WARRANTY; without even the implied
* warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. For
* details, see the GNU AGPL at: http://www.gnu.org/licenses/agpl-3.0.html
*
* You can contact Ascensio System SIA at 20A-6 Ernesta Birznieka-Upish
* street, Riga, Latvia, EU, LV-1050.
*
* The interactive user interfaces in modified source and object code versions
* of the Program must display Appropriate Legal Notices, as required under
* Section 5 of the GNU AGPL version 3.
*
* Pursuant to Section 7(b) of the License you must retain the original Product
* logo when distributing the program. Pursuant to Section 7(e) we decline to
* grant you any rights under trademark law for use of our trademarks.
*
* All the Product's GUI elements, including illustrations and icon sets, as
* well as technical writing content are licensed under the terms of the
* Creative Commons Attribution-ShareAlike 4.0 International. See the License
* terms at http://creativecommons.org/licenses/by-sa/4.0/legalcode
*
*/
"use strict";
(/**
* @param {Window} window
* @param {undefined} undefined
*/
function (window, undefined) {
var cDate = Asc.cDate;
var g_oFormatParser = AscCommon.g_oFormatParser;
var cErrorType = AscCommonExcel.cErrorType;
var c_sPerDay = AscCommonExcel.c_sPerDay;
var c_msPerDay = AscCommonExcel.c_msPerDay;
var cNumber = AscCommonExcel.cNumber;
var cString = AscCommonExcel.cString;
var cBool = AscCommonExcel.cBool;
var cError = AscCommonExcel.cError;
var cArea = AscCommonExcel.cArea;
var cArea3D = AscCommonExcel.cArea3D;
var cRef = AscCommonExcel.cRef;
var cRef3D = AscCommonExcel.cRef3D;
var cEmpty = AscCommonExcel.cEmpty;
var cArray = AscCommonExcel.cArray;
var cBaseFunction = AscCommonExcel.cBaseFunction;
var cFormulaFunctionGroup = AscCommonExcel.cFormulaFunctionGroup;
var cElementType = AscCommonExcel.cElementType;
var argType = Asc.c_oAscFormulaArgumentType;
var GetDiffDate360 = AscCommonExcel.GetDiffDate360;
var cExcelDateTimeDigits = 8; //количество цифр после запятой в числах отвечающих за время специализация $18.17.4.2
var DayCountBasis = {
// US 30/360
UsPsa30_360: 0, // Actual/Actual
ActualActual: 1, // Actual/360
Actual360: 2, // Actual/365
Actual365: 3, // European 30/360
Europ30_360: 4
};
function yearFrac(d1, d2, mode) {
d1.truncate();
d2.truncate();
var date1 = d1.getUTCDate(), month1 = d1.getUTCMonth() + 1, year1 = d1.getUTCFullYear(),
date2 = d2.getUTCDate(), month2 = d2.getUTCMonth() + 1, year2 = d2.getUTCFullYear();
switch (mode) {
case DayCountBasis.UsPsa30_360:
return new cNumber(Math.abs(GetDiffDate360(date1, month1, year1, date2, month2, year2, true)) / 360);
case DayCountBasis.ActualActual:
var yc = Math.abs(year2 - year1), sd = year1 > year2 ? new cDate(d2) : new cDate(d1),
yearAverage = sd.isLeapYear() ? 366 : 365, dayDiff = /*Math.abs*/(d2 - d1);
for (var i = 0; i < yc; i++) {
sd.addYears(1);
yearAverage += sd.isLeapYear() ? 366 : 365;
}
yearAverage /= (yc + 1);
dayDiff /= (yearAverage * c_msPerDay);
return new cNumber(Math.abs(dayDiff));
case DayCountBasis.Actual360:
var dayDiff = Math.abs(d2 - d1);
dayDiff /= (360 * c_msPerDay);
return new cNumber(dayDiff);
case DayCountBasis.Actual365:
var dayDiff = Math.abs(d2 - d1);
dayDiff /= (365 * c_msPerDay);
return new cNumber(dayDiff);
case DayCountBasis.Europ30_360:
return new cNumber(Math.abs(GetDiffDate360(date1, month1, year1, date2, month2, year2, false)) / 360);
default:
return new cError(cErrorType.not_numeric);
}
}
function diffDate(d1, d2, mode) {
var date1 = d1.getUTCDate(), month1 = d1.getUTCMonth() + 1, year1 = d1.getUTCFullYear(),
date2 = d2.getUTCDate(), month2 = d2.getUTCMonth() + 1, year2 = d2.getUTCFullYear();
switch (mode) {
case DayCountBasis.UsPsa30_360:
return new cNumber(GetDiffDate360(date1, month1, year1, date2, month2, year2, true));
case DayCountBasis.ActualActual:
return new cNumber((d2 - d1) / c_msPerDay);
case DayCountBasis.Actual360:
var dayDiff = d2 - d1;
dayDiff /= c_msPerDay;
return new cNumber((d2 - d1) / c_msPerDay);
case DayCountBasis.Actual365:
var dayDiff = d2 - d1;
dayDiff /= c_msPerDay;
return new cNumber((d2 - d1) / c_msPerDay);
case DayCountBasis.Europ30_360:
return new cNumber(GetDiffDate360(date1, month1, year1, date2, month2, year2, false));
default:
return new cError(cErrorType.not_numeric);
}
}
function diffDate2(d1, d2, mode) {
var date1 = d1.getUTCDate(), month1 = d1.getUTCMonth(), year1 = d1.getUTCFullYear(), date2 = d2.getUTCDate(),
month2 = d2.getUTCMonth(), year2 = d2.getUTCFullYear();
var nDaysInYear, nYears, nDayDiff;
switch (mode) {
case DayCountBasis.UsPsa30_360:
nDaysInYear = 360;
nYears = year1 - year2;
nDayDiff = Math.abs(GetDiffDate360(date1, month1 + 1, year1, date2, month2 + 1, year2, true)) -
nYears * nDaysInYear;
return new cNumber(nYears + nDayDiff / nDaysInYear);
case DayCountBasis.ActualActual:
nYears = year2 - year1;
nDaysInYear = d1.isLeapYear() ? 366 : 365;
var dayDiff;
if (nYears && (month1 > month2 || (month1 == month2 && date1 > date2))) {
nYears--;
}
if (nYears) {
dayDiff = parseInt((d2 - new cDate(Date.UTC(year2, month1, date1))) / c_msPerDay);
} else {
dayDiff = parseInt((d2 - d1) / c_msPerDay);
}
if (dayDiff < 0) {
dayDiff += nDaysInYear;
}
return new cNumber(nYears + dayDiff / nDaysInYear);
case DayCountBasis.Actual360:
nDaysInYear = 360;
nYears = parseInt((d2 - d1) / c_msPerDay / nDaysInYear);
nDayDiff = (d2 - d1) / c_msPerDay;
nDayDiff %= nDaysInYear;
return new cNumber(nYears + nDayDiff / nDaysInYear);
case DayCountBasis.Actual365:
nDaysInYear = 365;
nYears = parseInt((d2 - d1) / c_msPerDay / nDaysInYear);
nDayDiff = (d2 - d1) / c_msPerDay;
nDayDiff %= nDaysInYear;
return new cNumber(nYears + nDayDiff / nDaysInYear);
case DayCountBasis.Europ30_360:
nDaysInYear = 360;
nYears = year1 - year2;
nDayDiff = Math.abs(GetDiffDate360(date1, month1 + 1, year1, date2, month2 + 1, year2, false)) -
nYears * nDaysInYear;
return new cNumber(nYears + nDayDiff / nDaysInYear);
default:
return new cError(cErrorType.not_numeric);
}
}
function GetDiffDate(d1, d2, nMode, av) {
var bNeg = d1 > d2, nRet, pOptDaysIn1stYear;
if (bNeg) {
var n = d2;
d2 = d1;
d1 = n;
}
var nD1 = d1.getUTCDate(), nM1 = d1.getUTCMonth(), nY1 = d1.getUTCFullYear(), nD2 = d2.getUTCDate(),
nM2 = d2.getUTCMonth(), nY2 = d2.getUTCFullYear();
switch (nMode) {
case DayCountBasis.UsPsa30_360: // 0=USA (NASD) 30/360
case DayCountBasis.Europ30_360: { // 4=Europe 30/360
var bLeap = d1.isLeapYear(), nDays, nMonths/*, nYears*/;
nMonths = nM2 - nM1;
nDays = nD2 - nD1;
nMonths += (nY2 - nY1) * 12;
nRet = nMonths * 30 + nDays;
if (nMode == 0 && nM1 == 2 && nM2 != 2 && nY1 == nY2) {
nRet -= bLeap ? 1 : 2;
}
pOptDaysIn1stYear = 360;
break;
}
case DayCountBasis.ActualActual: // 1=exact/exact
pOptDaysIn1stYear = d1.isLeapYear() ? 366 : 365;
nRet = d2 - d1;
break;
case DayCountBasis.Actual360: // 2=exact/360
nRet = d2 - d1;
pOptDaysIn1stYear = 360;
break;
case DayCountBasis.Actual365: //3=exact/365
nRet = d2 - d1;
pOptDaysIn1stYear = 365;
break;
}
return (bNeg ? -nRet : nRet) / c_msPerDay / (av ? 1 : pOptDaysIn1stYear);
}
function days360(date1, date2, flag, isAccrint) {
let sign;
let nY1 = date1.getUTCFullYear(), nM1 = date1.getUTCMonth() + 1, nD1 = date1.getUTCDate(),
nY2 = date2.getUTCFullYear(), nM2 = date2.getUTCMonth() + 1, nD2 = date2.getUTCDate();
if (flag && !isAccrint && (date2 < date1)) {
sign = date1;
date1 = date2;
date2 = sign;
sign = -1;
} else {
sign = 1;
}
if (nD1 == 31) {
nD1 -= 1;
} else if (!flag) {
if (nM1 == 2) {
switch (nD1) {
case 28 :
if (!date1.isLeapYear()) {
nD1 = 30;
}
break;
case 29 :
nD1 = 30;
break;
}
}
}
if (nD2 == 31) {
if (!flag) {
if (nD1 == 30) {
nD2--;
}
} else {
nD2 = 30;
}
}
return sign * (nD2 - nD1 + (nM2 - nM1) * 30 + (nY2 - nY1) * 360);
}
function daysInYear(date, basis) {
switch (basis) {
case DayCountBasis.UsPsa30_360: // 0=USA (NASD) 30/360
case DayCountBasis.Actual360: // 2=exact/360
case DayCountBasis.Europ30_360: // 4=Europe 30/360
return new cNumber(360);
case DayCountBasis.ActualActual: { // 1=exact/exact
var d = cDate.prototype.getDateFromExcel(date);
return new cNumber(d.isLeapYear() ? 366 : 365);
}
case DayCountBasis.Actual365: //3=exact/365
return new cNumber(365);
default:
return new cError(cErrorType.not_numeric);
}
}
function getCorrectDate(val) {
if (!AscCommon.bDate1904) {
if (val < 60) {
val = new cDate((val - AscCommonExcel.c_DateCorrectConst) * c_msPerDay);
} else if (val == 60) {
val = new cDate((val - AscCommonExcel.c_DateCorrectConst - 1) * c_msPerDay);
} else {
val = new cDate((val - AscCommonExcel.c_DateCorrectConst - 1) * c_msPerDay);
}
} else {
val = new cDate((val - AscCommonExcel.c_DateCorrectConst) * c_msPerDay);
}
return val;
}
function getCorrectDate2(val) {
if (!AscCommon.bDate1904) {
val = new cDate((val - AscCommonExcel.c_DateCorrectConst - 1) * c_msPerDay);
} else {
val = new cDate((val - AscCommonExcel.c_DateCorrectConst) * c_msPerDay);
}
return val;
}
function getWeekends(val) {
var res = [];
if (val) {
if (cElementType.number === val.type) {
//0 - SUNDAY, 1 - MONDAY, 2 - TUESDAY, 3 - WEDNESDAY, 4 - THURSDAY, 5 - FRIDAY, 6 - SATURDAY
var numberVal = val.getValue();
switch (numberVal) {
case 1 :
res[6] = true;
res[0] = true;
break;
case 2 :
res[0] = true;
res[1] = true;
break;
case 3 :
res[1] = true;
res[2] = true;
break;
case 4 :
res[2] = true;
res[3] = true;
break;
case 5 :
res[3] = true;
res[4] = true;
break;
case 6 :
res[4] = true;
res[5] = true;
break;
case 7 :
res[5] = true;
res[6] = true;
break;
case 11 :
res[0] = true;
break;
case 12 :
res[1] = true;
break;
case 13 :
res[2] = true;
break;
case 14 :
res[3] = true;
break;
case 15 :
res[4] = true;
break;
case 16 :
res[5] = true;
break;
case 17 :
res[6] = true;
break;
default :
return new cError(cErrorType.not_numeric);
}
} else if (cElementType.string === val.type) {
var stringVal = val.getValue();
if (stringVal.length !== 7) {
return new cError(cErrorType.wrong_value_type);
}
//start with monday
for (var i = 0; i < 7; i++) {
var num = 6 === i ? 0 : i + 1;
switch (stringVal[i]) {
case '0' :
res[num] = false;
break;
case '1' :
res[num] = true;
break;
default :
return new cError(cErrorType.wrong_value_type);
}
}
} else {
return new cError(cErrorType.not_numeric);
}
} else {
res[6] = true;
res[0] = true;
}
return res;
}
function getHolidays(val) {
var holidays = [];
if (val) {
if (val instanceof cRef) {
var a = val.getValue();
if (a instanceof cNumber && a.getValue() >= 0) {
holidays.push(a);
}
} else if (val instanceof cArea || val instanceof cArea3D) {
var arr = val.getValue();
for (var i = 0; i < arr.length; i++) {
if (arr[i] instanceof cNumber && arr[i].getValue() >= 0) {
holidays.push(arr[i]);
}
}
} else if (val instanceof cArray) {
var bIsError = false;
val.foreach(function (elem) {
if (elem instanceof cNumber) {
holidays.push(elem);
} else if (elem instanceof cString) {
var res = elem.tocNumber();
if (res instanceof cError || res instanceof cEmpty) {
var d = new cDate(elem.getValue());
if (isNaN(d)) {
d = g_oFormatParser.parseDate(elem.getValue(), AscCommon.g_oDefaultCultureInfo);
if (d === null) {
return new cError(cErrorType.wrong_value_type);
}
res = d.value;
} else {
res = (d.getTime() / 1000 - d.getTimezoneOffset() * 60) / c_sPerDay +
(AscCommonExcel.c_DateCorrectConst + (AscCommon.bDate1904 ? 0 : 1));
}
} else {
res = elem.tocNumber().getValue();
}
if (res && res > 0) {
holidays.push(new cNumber(parseInt(res)));
} else {
return bIsError = new cError(cErrorType.wrong_value_type);
}
}
});
if (bIsError) {
return bIsError;
}
} else {
val = val.tocNumber();
if (val instanceof cError) {
return bIsError = new cError(val);
} else if (val instanceof cNumber) {
holidays.push(val);
}
}
}
for (var i = 0; i < holidays.length; i++) {
holidays[i] = cDate.prototype.getDateFromExcel(holidays[i].getValue());
}
return holidays;
}
function _includeInHolidays(date, holidays) {
for (var i = 0; i < holidays.length; i++) {
if (date.getTime() == holidays[i].getTime()) {
return true;
}
}
return false;
}
function _includeInHolidaysTime(time, holidays) {
for (var i = 0; i < holidays.length; i++) {
if (time == holidays[i].getTime()) {
return true;
}
}
return false;
}
function weekNumber(dt, iso, type) {
if (undefined === iso) {
iso = [0, 1, 2, 3, 4, 5, 6];
}
if (undefined === type) {
type = 0;
}
dt.setUTCHours(0, 0, 0);
var utcFullYear = dt.getUTCFullYear();
if (type) {
//если это исключение не обработать, то будет бесконечная рекурсия
utcFullYear = Date.prototype.getUTCFullYear.call(dt);
}
var startOfYear = new cDate(Date.UTC(utcFullYear, 0, 1));
var endOfYear = new cDate(dt);
endOfYear.setUTCMonth(11);
endOfYear.setUTCDate(31);
var wk = parseInt(((dt - startOfYear) / c_msPerDay + iso[startOfYear.getUTCDay()]) / 7);
if (type) {
switch (wk) {
case 0:
// Возвращаем номер недели от 31 декабря предыдущего года
startOfYear.setUTCDate(0);
return weekNumber(startOfYear, iso, type);
case 53:
// Если 31 декабря выпадает до четверга 1 недели следующего года
if (endOfYear.getUTCDay() < 4) {
return new cNumber(1);
} else {
return new cNumber(wk);
}
default:
return new cNumber(wk);
}
} else {
wk = parseInt(((dt - startOfYear) / c_msPerDay + iso[startOfYear.getUTCDay()] + 7) / 7);
return new cNumber(wk);
}
}
/**
* Returns the last day in the month in Date format.
* @param {number} nExcelDateVal
* @param {number} nMonths - The number of months before or after nExcelDateVal.
* A positive value for months yields a future date; a negative value yields a past date.
* @returns {cDate}
*/
function getLastDayInMonth (nExcelDateVal, nMonths) {
let dtValue;
if (!AscCommon.bDate1904) {
if (nExcelDateVal === 0) {
dtValue = new cDate((nExcelDateVal - AscCommonExcel.c_DateCorrectConst + 1) * c_msPerDay);
} else if (nExcelDateVal < 60) {
dtValue = new cDate((nExcelDateVal - AscCommonExcel.c_DateCorrectConst) * c_msPerDay);
} else if (nExcelDateVal === 60) {
dtValue = new cDate((nExcelDateVal - AscCommonExcel.c_DateCorrectConst - 1) * c_msPerDay);
} else {
dtValue = new cDate((nExcelDateVal - AscCommonExcel.c_DateCorrectConst - 1) * c_msPerDay);
}
} else {
dtValue = new cDate((nExcelDateVal - AscCommonExcel.c_DateCorrectConst) * c_msPerDay);
}
// setUTCDate doesn't work properly for -UTC time
dtValue.setUTCDate(1);
dtValue.setUTCMonth(dtValue.getUTCMonth() + nMonths);
dtValue.setUTCDate(dtValue.getDaysInMonth());
return dtValue;
}
cFormulaFunctionGroup['DateAndTime'] = cFormulaFunctionGroup['DateAndTime'] || [];
cFormulaFunctionGroup['DateAndTime'].push(cDATE, cDATEDIF, cDATEVALUE, cDAY, cDAYS, cDAYS360, cEDATE, cEOMONTH,
cHOUR, cISOWEEKNUM, cMINUTE, cMONTH, cNETWORKDAYS, cNETWORKDAYS_INTL, cNOW, cSECOND, cTIME, cTIMEVALUE, cTODAY,
cWEEKDAY, cWEEKNUM, cWORKDAY, cWORKDAY_INTL, cYEAR, cYEARFRAC);
/**
* @constructor
* @extends {AscCommonExcel.cBaseFunction}
*/
function cDATE() {
}
//***array-formula***
cDATE.prototype = Object.create(cBaseFunction.prototype);
cDATE.prototype.constructor = cDATE;
cDATE.prototype.name = 'DATE';
cDATE.prototype.argumentsMin = 3;
cDATE.prototype.argumentsMax = 3;
cDATE.prototype.argumentsType = [argType.number, argType.number, argType.number];
cDATE.prototype.Calculate = function (arg) {
var arg0 = arg[0], arg1 = arg[1], arg2 = arg[2], year, month, day;
if (arg0 instanceof cArea || arg0 instanceof cArea3D) {
arg0 = arg0.cross(arguments[1]);
} else if (arg0 instanceof cArray) {
arg0 = arg0.getElement(0);
}
if (arg1 instanceof cArea || arg1 instanceof cArea3D) {
arg1 = arg1.cross(arguments[1]);
} else if (arg1 instanceof cArray) {
arg1 = arg1.getElement(0);
}
if (arg2 instanceof cArea || arg2 instanceof cArea3D) {
arg2 = arg2.cross(arguments[1]);
} else if (arg2 instanceof cArray) {
arg2 = arg2.getElement(0);
}
arg0 = arg0.tocNumber();
arg1 = arg1.tocNumber();
arg2 = arg2.tocNumber();
if (arg0 instanceof cError) {
return arg0;
}
if (arg1 instanceof cError) {
return arg1;
}
if (arg2 instanceof cError) {
return arg2;
}
year = arg0.getValue();
month = arg1.getValue();
day = arg2.getValue();
if (year >= 0 && year <= 1899) {
year += 1900;
}
var res;
if (year === 1900 && month === 2 && day === 29) {
res = new cNumber(60);
} else {
var _num = Math.round(new cDate(Date.UTC(year, month - 1, day)).getExcelDate());
if (_num < 0) {
return new cError(cErrorType.not_numeric);
}
res = new cNumber(_num);
}
res.numFormat = 14;
return res;
};
/**
* @constructor
* @extends {AscCommonExcel.cBaseFunction}
*/
function cDATEDIF() {
}
//***array-formula***
cDATEDIF.prototype = Object.create(cBaseFunction.prototype);
cDATEDIF.prototype.constructor = cDATEDIF;
cDATEDIF.prototype.name = 'DATEDIF';
cDATEDIF.prototype.argumentsMin = 3;
cDATEDIF.prototype.argumentsMax = 3;
cDATEDIF.prototype.numFormat = AscCommonExcel.cNumFormatNone;
cDATEDIF.prototype.argumentsType = [argType.number, argType.number, argType.text];
cDATEDIF.prototype.Calculate = function (arg) {
let arg0 = arg[0], arg1 = arg[1], arg2 = arg[2];
// --------------- check first argument[arg0] ----------------//
if (cElementType.cellsRange === arg0.type || cElementType.cellsRange3D === arg0.type) {
arg0 = arg0.cross(arguments[1]);
} else if (cElementType.array === arg0.type) {
arg0 = arg0.getElementRowCol(0, 0);
}
// --------------- check second argument[arg1] ----------------//
if (cElementType.cellsRange === arg1.type || cElementType.cellsRange3D === arg1.type) {
arg1 = arg1.cross(arguments[1]);
} else if (cElementType.array === arg1.type) {
arg1 = arg1.getElementRowCol(0, 0);
}
// --------------- check third argument[arg2] ----------------//
if (cElementType.cellsRange === arg2.type || cElementType.cellsRange3D === arg2.type) {
arg2 = arg2.cross(arguments[1]);
} else if (cElementType.array === arg2.type) {
arg2 = arg2.getElementRowCol(0, 0);
}
arg0 = arg0.tocNumber();
arg1 = arg1.tocNumber();
arg2 = arg2.tocString();
if (cElementType.error === arg0.type) {
return arg0;
}
if (cElementType.error === arg1.type) {
return arg1;
}
if (cElementType.error === arg2.type) {
return arg2;
}
let val0 = arg0.getValue(), val1 = arg1.getValue();
if (val0 < 0 || val1 < 0 || val0 > val1) {
return new cError(cErrorType.not_numeric);
}
// TODO при передаче в аргументы числовых значений в единственном числе, итоговая дата различается с той что в ms на 1 день, из-за этого результаты могут различатся
val0 = cDate.prototype.getDateFromExcel(val0);
val1 = cDate.prototype.getDateFromExcel(val1);
function newDateDiff(date1, date2) {
const results = {
years: date2.getUTCFullYear() - date1.getUTCFullYear(),
months: date2.getUTCMonth() - date1.getUTCMonth(),
days: date2.getUTCDate() - date1.getUTCDate(),
hours: date2.getUTCHours() - date1.getUTCHours()
}
if (results.hours < 0) {
results.days--;
results.hours += 24;
}
if (results.days < 0) {
let copy1 = new Date(date1.getTime());
copy1.setDate(32);
results.months--;
results.days = 32 - date1.getUTCDate() - copy1.getUTCDate() + date2.getUTCDate();
}
if (results.months < 0) {
results.years--;
results.months += 12;
}
let years = results.years;
let months = results.years * 12 + results.months;
let days = results.days;
return [years, months, days];
}
// function dateDiff(date1, date2) {
// var years = date2.getUTCFullYear() - date1.getUTCFullYear();
// var months = years * 12 + date2.getUTCMonth() - date1.getUTCMonth();
// var days = date2.getUTCDate() - date1.getUTCDate();
// var daysDiff = (date2 - date1) / c_msPerDay; // ms -> s -> m -> h -> d
// years -= date2.getUTCMonth() < date1.getUTCMonth();
// months -= date2.getUTCDate() < date1.getUTCDate();
// days += days < 0 ? new cDate(Date.UTC(date2.getUTCFullYear(), date2.getUTCMonth() - 1, 0)).getUTCDate() + 1 : 0;
// if(years === 1 && daysDiff < 365) {
// years = 0;
// }
// return [years, months, days];
// }
switch (arg2.getValue().toUpperCase()) {
case "Y":
return new cNumber(newDateDiff(val0, val1)[0]);
break;
case "M":
return new cNumber(newDateDiff(val0, val1)[1]);
break;
case "D":
return new cNumber(parseInt((val1 - val0) / c_msPerDay));
break;
case "MD":
if (val0.getUTCDate() > val1.getUTCDate()) {
return new cNumber(Math.abs(
new cDate(Date.UTC(val0.getUTCFullYear(), val0.getUTCMonth(), val0.getUTCDate())) -
new cDate(Date.UTC(val0.getUTCFullYear(), val0.getUTCMonth() + 1, val1.getUTCDate()))) /
c_msPerDay);
} else {
return new cNumber(val1.getUTCDate() - val0.getUTCDate());
}
break;
case "YM":
let d = newDateDiff(val0, val1);
return new cNumber(d[1] - d[0] * 12);
break;
case "YD":
if (val0.getUTCMonth() > val1.getUTCMonth()) {
return new cNumber(Math.abs(
new cDate(Date.UTC(val0.getUTCFullYear(), val0.getUTCMonth(), val0.getUTCDate())) -
new cDate(Date.UTC(val0.getUTCFullYear() + 1, val1.getUTCMonth(), val1.getUTCDate()))) /
c_msPerDay);
} else {
return new cNumber(Math.abs(
new cDate(Date.UTC(val0.getUTCFullYear(), val0.getUTCMonth(), val0.getUTCDate())) -
new cDate(Date.UTC(val0.getUTCFullYear(), val1.getUTCMonth(), val1.getUTCDate()))) /
c_msPerDay);
}
break;
default:
return new cError(cErrorType.not_numeric)
}
};
/**
* @constructor
* @extends {AscCommonExcel.cBaseFunction}
*/
function cDATEVALUE() {
}
//***array-formula***
cDATEVALUE.prototype = Object.create(cBaseFunction.prototype);
cDATEVALUE.prototype.constructor = cDATEVALUE;
cDATEVALUE.prototype.name = 'DATEVALUE';
cDATEVALUE.prototype.argumentsMin = 1;
cDATEVALUE.prototype.argumentsMax = 1;
cDATEVALUE.prototype.numFormat = AscCommonExcel.cNumFormatNone;
cDATEVALUE.prototype.argumentsType = [argType.number];
cDATEVALUE.prototype.Calculate = function (arg) {
var arg0 = arg[0];
if (arg0 instanceof cArea || arg0 instanceof cArea3D) {
arg0 = arg0.cross(arguments[1]);
} else if (arg0 instanceof cArray) {
arg0 = arg0.getElementRowCol(0, 0);
}
arg0 = arg0.tocString();
if (arg0 instanceof cError) {
return arg0;
}
var res = g_oFormatParser.parse(arg0.getValue());
if (res && res.bDateTime) {
return new cNumber(parseInt(res.value));
} else {
return new cError(cErrorType.wrong_value_type);
}
};
/**
* @constructor
* @extends {AscCommonExcel.cBaseFunction}
*/
function cDAY() {
}
//***array-formula***
cDAY.prototype = Object.create(cBaseFunction.prototype);
cDAY.prototype.constructor = cDAY;
cDAY.prototype.name = 'DAY';
cDAY.prototype.argumentsMin = 1;
cDAY.prototype.argumentsMax = 1;
cDAY.prototype.numFormat = AscCommonExcel.cNumFormatNone;
cDAY.prototype.argumentsType = [argType.number];
cDAY.prototype.Calculate = function (arg) {
var t = this;
var bIsSpecialFunction = arguments[4];
var calculateFunc = function (curArg) {
var val;
if (curArg instanceof cArray) {
curArg = curArg.getElement(0);
} else if (curArg instanceof cArea || curArg instanceof cArea3D) {
curArg = curArg.cross(arguments[1]).tocNumber();
val = curArg.tocNumber().getValue();
}
if (curArg instanceof cError) {
return curArg;
} else if (curArg instanceof cNumber || curArg instanceof cBool || curArg instanceof cEmpty) {
val = curArg.tocNumber().getValue();
} else if (curArg instanceof cRef || curArg instanceof cRef3D) {
val = curArg.getValue().tocNumber();
if (val instanceof cNumber || val instanceof cBool || curArg instanceof cEmpty) {
val = curArg.tocNumber().getValue();
} else {
return new cError(cErrorType.wrong_value_type);
}
} else if (curArg instanceof cString) {
val = curArg.tocNumber();
if (val instanceof cError || val instanceof cEmpty) {
var d = new cDate(curArg.getValue());
if (isNaN(d)) {
return new cError(cErrorType.wrong_value_type);
} else {
val = Math.floor((d.getTime() / 1000 - d.getTimezoneOffset() * 60) / c_sPerDay +
(AscCommonExcel.c_DateCorrectConst + (AscCommon.bDate1904 ? 0 : 1)));
}
} else {
val = curArg.tocNumber().getValue();
}
}
if (val < 0) {
return new cError(cErrorType.not_numeric);
} else if (!AscCommon.bDate1904) {
if (val < 60) {
return t.setCalcValue(
new cNumber((new cDate((val - AscCommonExcel.c_DateCorrectConst) * c_msPerDay)).getUTCDate()), 0);
} else if (val == 60) {
return t.setCalcValue(new cNumber(
(new cDate((val - AscCommonExcel.c_DateCorrectConst - 1) * c_msPerDay)).getUTCDate() + 1), 0);
} else {
return t.setCalcValue(
new cNumber((new cDate((val - AscCommonExcel.c_DateCorrectConst - 1) * c_msPerDay)).getUTCDate()),
0);
}
} else {
return t.setCalcValue(
new cNumber((new cDate((val - AscCommonExcel.c_DateCorrectConst) * c_msPerDay)).getUTCDate()), 0);
}
};
var arg0 = arg[0], res;
if (!bIsSpecialFunction) {
if (arg0 instanceof cArray) {
arg0 = arg0.getElement(0);
} else if (arg0 instanceof cArea || arg0 instanceof cArea3D) {
arg0 = arg0.cross(arguments[1]).tocNumber();
}
res = calculateFunc(arg0);
} else {
res = this._checkArrayArguments(arg0, calculateFunc);
}
return res;
};
/**
* @constructor
* @extends {AscCommonExcel.cBaseFunction}
*/
function cDAYS() {
}
//***array-formula***
cDAYS.prototype = Object.create(cBaseFunction.prototype);
cDAYS.prototype.constructor = cDAYS;
cDAYS.prototype.name = 'DAYS';
cDAYS.prototype.argumentsMin = 2;
cDAYS.prototype.argumentsMax = 2;
cDAYS.prototype.numFormat = AscCommonExcel.cNumFormatNone;
cDAYS.prototype.isXLFN = true;
cDAYS.prototype.argumentsType = [argType.number, argType.number];
cDAYS.prototype.Calculate = function (arg) {
let oArguments = this._prepareArguments(arg, arguments[1], true);
let argClone = oArguments.args;
const calulateDay = function (curArg) {
let val;
if (curArg.type === cElementType.cell || curArg.type === cElementType.cell3D) {
curArg = curArg.getValue();
} else if (curArg.type === cElementType.array) {
curArg = curArg.getElement(0);
} else if (curArg.type === cElementType.cellsRange || curArg.type === cElementType.cellsRange3D) {
curArg = curArg.cross(arguments[1]);
}
val = curArg ? curArg : new cNumber(0);
if (val.type === cElementType.error) {
return val;
} else if (val.type === cElementType.number || val.type === cElementType.bool || val.type === cElementType.empty) {
val = val.tocNumber().getValue();
} else if (val.type === cElementType.string) {
val = val.tocNumber();
if (val.type === cElementType.error || val.type === cElementType.empty) {
let d = new cDate(val.getValue());
if (isNaN(d)) {
return new cError(cErrorType.wrong_value_type);
} else {
val = Math.floor((d.getTime() / 1000 - d.getTimezoneOffset() * 60) / c_sPerDay +
(AscCommonExcel.c_DateCorrectConst + (AscCommon.bDate1904 ? 0 : 1)));
}
} else {
val = val.tocNumber().getValue();
}
}
return val;
};
const calulateDays = function (argArray) {
let end_date = calulateDay(argArray[0]);
let start_date = calulateDay(argArray[1]);
if (end_date.type === cElementType.error) {
return end_date;
} else if (start_date.type === cElementType.error) {
return start_date;
}
if (end_date < 0 || start_date < 0) {
return new cError(cErrorType.not_numeric);
} else {
let endInteger = Math.floor(end_date);
let startInteger = Math.floor(start_date);
return new cNumber(endInteger - startInteger);
}
};
return calulateDays(argClone);
};
/**
* @constructor
* @extends {AscCommonExcel.cBaseFunction}
*/
function cDAYS360() {
}
//***array-formula***
cDAYS360.prototype = Object.create(cBaseFunction.prototype);
cDAYS360.prototype.constructor = cDAYS360;
cDAYS360.prototype.name = 'DAYS360';
cDAYS360.prototype.argumentsMin = 2;
cDAYS360.prototype.argumentsMax = 3;
cDAYS360.prototype.numFormat = AscCommonExcel.cNumFormatNone;
cDAYS360.prototype.argumentsType = [argType.number, argType.number, argType.logical];
cDAYS360.prototype.Calculate = function (arg) {
var arg0 = arg[0], arg1 = arg[1], arg2 = arg[2] ? arg[2] : new cBool(false);
if (arg0 instanceof cArea || arg0 instanceof cArea3D) {
arg0 = arg0.cross(arguments[1]);
} else if (arg0 instanceof cArray) {
arg0 = arg0.getElementRowCol(0, 0);
}
if (arg1 instanceof cArea || arg1 instanceof cArea3D) {
arg1 = arg1.cross(arguments[1]);
} else if (arg1 instanceof cArray) {
arg1 = arg1.getElementRowCol(0, 0);
}
if (arg2 instanceof cArea || arg2 instanceof cArea3D) {
arg2 = arg2.cross(arguments[1]);
} else if (arg2 instanceof cArray) {
arg2 = arg2.getElementRowCol(0, 0);
}
arg0 = arg0.tocNumber();
arg1 = arg1.tocNumber();
arg2 = arg2.tocBool();
if (arg0 instanceof cError) {
return arg0;
}
if (arg1 instanceof cError) {
return arg1;
}
if (arg2 instanceof cError) {
return arg2;
}
if (arg0.getValue() < 0) {
return new cError(cErrorType.not_numeric);
}
if (arg1.getValue() < 0) {
return new cError(cErrorType.not_numeric);
}
var date1 = cDate.prototype.getDateFromExcel(arg0.getValue()),
date2 = cDate.prototype.getDateFromExcel(arg1.getValue());
return new cNumber(days360(date1, date2, arg2.toBool()));
};
/**
* @constructor
* @extends {AscCommonExcel.cBaseFunction}
*/
function cEDATE() {
}
//***array-formula***
cEDATE.prototype = Object.create(cBaseFunction.prototype);
cEDATE.prototype.constructor = cEDATE;
cEDATE.prototype.name = 'EDATE';
cEDATE.prototype.argumentsMin = 2;
cEDATE.prototype.argumentsMax = 2;
cEDATE.prototype.numFormat = AscCommonExcel.cNumFormatNone;
cEDATE.prototype.returnValueType = AscCommonExcel.cReturnFormulaType.value_replace_area;
cEDATE.prototype.argumentsType = [argType.any, argType.any];
cEDATE.prototype.Calculate = function (arg) {
let arg0 = arg[0], arg1 = arg[1];
if (arg0.type === cElementType.cellsRange || arg0.type === cElementType.cellsRange3D) {
let dimensions = arg0.getDimensions();
if (dimensions.row > 1 || dimensions.col > 1) {
return new cError(cErrorType.wrong_value_type);
}
arg0 = arg0.getFirstElement();
} else if (arg0.type === cElementType.array) {
arg0 = arg0.getElementRowCol(0, 0);
} else if (arg0.type === cElementType.bool) {
return new cError(cErrorType.wrong_value_type);
}
if (arg1.type === cElementType.cellsRange || arg1.type === cElementType.cellsRange3D) {
let dimensions = arg1.getDimensions();
if (dimensions.row > 1 || dimensions.col > 1) {
return new cError(cErrorType.wrong_value_type);
}
arg1 = arg1.getFirstElement();
} else if (arg1.type === cElementType.array) {
arg1 = arg1.getElementRowCol(0, 0);
} else if (arg1.type === cElementType.bool) {
return new cError(cErrorType.wrong_value_type);
}
if (arg0.type === cElementType.empty || arg1.type === cElementType.empty) {
return new cError(cErrorType.not_available);
}
arg0 = arg0.tocNumber();
arg1 = arg1.tocNumber();
if (arg0.type === cElementType.error) {
return arg0;
}
if (arg1.type === cElementType.error) {
return arg1;
}
let val = arg0.getValue(), addedMonths = arg1.getValue(), date, _date;
let now = new cDate();
let offsetInMinutes = now.getTimezoneOffset();
let offsetInHours = (offsetInMinutes / 60) * -1;
let UTCshift = offsetInHours >= 0 ? 1 : 0;
if (val < 0) {
return new cError(cErrorType.not_numeric);
} else if (addedMonths === 0) {
return arg0;
} else if (!AscCommon.bDate1904) {
if (val < 60) {
val = new cDate((Math.floor(val) - AscCommonExcel.c_DateCorrectConst) * c_msPerDay);
} else if (val === 60) {
// 29 february 1900 - exception - this date doesn't exist in js
// val = new cDate(Date.UTC( 1900, 1, 29 ));
val = new cDate((Math.floor(val) - AscCommonExcel.c_DateCorrectConst) * c_msPerDay);
} else {
val = new cDate((Math.floor(val) - AscCommonExcel.c_DateCorrectConst - UTCshift) * c_msPerDay);
}
} else {
val = new cDate((Math.floor(val) - AscCommonExcel.c_DateCorrectConst) * c_msPerDay);
}
date = new cDate(val);
let localDay = date.getDate(),
localMonth = date.getMonth(),
isLeap = date.isLeapYear();
if (0 <= localDay && 28 >= localDay) {
val = new cDate(val.setUTCMonth(val.getUTCMonth() + addedMonths))
} else if (29 <= localDay && 31 >= localDay) {
// Add the month separately. If the target month is February, the year is a leap year, and the day is greater than 28, return 28 or 29.
// It should not depend on UTC since we are working with an isolated date.
let newDay = localDay;
if (localMonth + addedMonths == 1) {
// set day to the last day of february
newDay = isLeap ? 29 : 28;
}
date.setDate(1);
date.setMonth(localMonth + addedMonths);
// get and compare last day of month
if (newDay > (_date = date.getLocalDaysInMonth())) {
date.setDate(_date)
} else {
date.setDate(newDay);
}
val = new cDate(date);
}
let res = Math.floor((val.getTime() / 1000 - val.getTimezoneOffset() * 60) / c_sPerDay + (AscCommonExcel.c_DateCorrectConst + 1));
if (res < 0) {
return new cError(cErrorType.not_numeric);
}
// shift for 1904 mode
if (AscCommon.bDate1904) {
res -= 1;
}
return new cNumber(res);
};
/**
* @constructor
* @extends {AscCommonExcel.cBaseFunction}
*/
function cEOMONTH() {
}
//***array-formula***
cEOMONTH.prototype = Object.create(cBaseFunction.prototype);
cEOMONTH.prototype.constructor = cEOMONTH;
cEOMONTH.prototype.name = 'EOMONTH';
cEOMONTH.prototype.argumentsMin = 2;
cEOMONTH.prototype.argumentsMax = 2;
cEOMONTH.prototype.numFormat = AscCommonExcel.cNumFormatNone;
cEOMONTH.prototype.returnValueType = AscCommonExcel.cReturnFormulaType.value_replace_area;
cEOMONTH.prototype.argumentsType = [argType.any, argType.any];
cEOMONTH.prototype.Calculate = function (arg) {
let arg0 = arg[0], arg1 = arg[1];
if (cElementType.cellsRange === arg0.type || cElementType.cellsRange3D === arg0.type) {
arg0 = arg0.cross(arguments[1]);
} else if (cElementType.array === arg0.type) {
arg0 = arg0.getElementRowCol(0, 0);
} else if (cElementType.cell === arg0.type || cElementType.cell3D === arg0.type) {
arg0 = arg0.getValue();
}
if (cElementType.cellsRange === arg1.type || cElementType.cellsRange3D === arg1.type) {
arg1 = arg1.cross(arguments[1]);
} else if (cElementType.array === arg1.type) {
arg1 = arg1.getElementRowCol(0, 0);
} else if (cElementType.cell === arg1.type || cElementType.cell3D === arg1.type) {
arg1 = arg1.getValue();
}
if (cElementType.bool === arg0.type) {
return new cError(cErrorType.wrong_value_type);
}
if (cElementType.bool === arg1.type) {
return new cError(cErrorType.wrong_value_type);
}
arg0 = arg0.tocNumber();
arg1 = arg1.tocNumber();
if (cElementType.error === arg0.type) {
return arg0;
}
if (cElementType.error === arg1.type) {
return arg1;
}
let val = arg0.getValue();
val = parseInt(val);
if (val < 0) {
return new cError(cErrorType.not_numeric);
}
val = getLastDayInMonth(val, arg1.getValue());
return new cNumber(Math.round(val.getExcelDateWithTime()));
};
/**
* @constructor
* @extends {AscCommonExcel.cBaseFunction}
*/
function cHOUR() {
}
//***array-formula***
cHOUR.prototype = Object.create(cBaseFunction.prototype);
cHOUR.prototype.constructor = cHOUR;
cHOUR.prototype.name = 'HOUR';
cHOUR.prototype.argumentsMin = 1;
cHOUR.prototype.argumentsMax = 1;
cHOUR.prototype.numFormat = AscCommonExcel.cNumFormatNone;
cHOUR.prototype.argumentsType = [argType.number];
cHOUR.prototype.Calculate = function (arg) {
var t = this;
var bIsSpecialFunction = arguments[4];
var calculateFunc = function (curArg) {
var val;
if (curArg instanceof cArray) {
curArg = curArg.getElement(0);
} else if (curArg instanceof cArea || curArg instanceof cArea3D) {
curArg = curArg.cross(arguments[1]).tocNumber();
}
if (curArg instanceof cError) {
return curArg;
} else if (curArg instanceof cNumber || curArg instanceof cBool || curArg instanceof cEmpty) {
val = curArg.tocNumber().getValue();
} else if (curArg instanceof cRef || curArg instanceof cRef3D) {
val = curArg.getValue();
if (val instanceof cError) {
return val;
} else if (val instanceof cNumber || val instanceof cBool || curArg instanceof cEmpty) {
val = curArg.tocNumber().getValue();
} else {
return new cError(cErrorType.wrong_value_type);
}
} else if (curArg instanceof cString) {
val = curArg.tocNumber();
if (val instanceof cError || val instanceof cEmpty) {
var d = new cDate(curArg.getValue());
if (isNaN(d)) {
d = g_oFormatParser.parseDate(curArg.getValue(), AscCommon.g_oDefaultCultureInfo);
if (d == null) {
return new cError(cErrorType.wrong_value_type);
}
val = d.value;
} else {
val = (d.getTime() / 1000 - d.getTimezoneOffset() * 60) / c_sPerDay + (AscCommonExcel.c_DateCorrectConst + (AscCommon.bDate1904 ? 0 : 1));
}
} else {
val = curArg.tocNumber().getValue();
}
}
if (val < 0) {
return new cError(cErrorType.not_numeric);
} else //1 2 3 4 4 3 2 1
{
return t.setCalcValue(new cNumber(parseInt(((val - Math.floor(val)) * 24).toFixed(cExcelDateTimeDigits))), 0);
}
};
var arg0 = arg[0], res;
if (!bIsSpecialFunction) {
if (arg0 instanceof cArray) {
arg0 = arg0.getElement(0);
} else if (arg0 instanceof cArea || arg0 instanceof cArea3D) {
arg0 = arg0.cross(arguments[1]).tocNumber();
}
res = calculateFunc(arg0);
} else {
res = this._checkArrayArguments(arg0, calculateFunc);
}
return res;
};
/**
* @constructor
* @extends {AscCommonExcel.cBaseFunction}
*/
function cISOWEEKNUM() {
}
//***array-formula***
cISOWEEKNUM.prototype = Object.create(cBaseFunction.prototype);
cISOWEEKNUM.prototype.constructor = cISOWEEKNUM;
cISOWEEKNUM.prototype.name = 'ISOWEEKNUM';
cISOWEEKNUM.prototype.argumentsMin = 1;
cISOWEEKNUM.prototype.argumentsMax = 1;
cISOWEEKNUM.prototype.numFormat = AscCommonExcel.cNumFormatNone;
cISOWEEKNUM.prototype.isXLFN = true;
cISOWEEKNUM.prototype.argumentsType = [argType.number];
cISOWEEKNUM.prototype.Calculate = function (arg) {
let oArguments = this._prepareArguments(arg, arguments[1], true);
let argClone = oArguments.args;
argClone[0] = argClone[0].tocNumber();
let argError;
if (argError = this._checkErrorArg(argClone)) {
return argError;
}
let arg0 = argClone[0];
if (arg0.getValue() < 0) {
return new cError(cErrorType.not_numeric);
}
let weekdayStartDay = [6, 7, 8, 9, 10, 4, 5], type = 1;
return new cNumber(weekNumber(cDate.prototype.getDateFromExcel(arg0.getValue()), weekdayStartDay, type));
};
/**
* @constructor
* @extends {AscCommonExcel.cBaseFunction}
*/
function cMINUTE() {
}
//***array-formula***
cMINUTE.prototype = Object.create(cBaseFunction.prototype);
cMINUTE.prototype.constructor = cMINUTE;
cMINUTE.prototype.name = 'MINUTE';
cMINUTE.prototype.argumentsMin = 1;
cMINUTE.prototype.argumentsMax = 1;
cMINUTE.prototype.numFormat = AscCommonExcel.cNumFormatNone;
cMINUTE.prototype.argumentsType = [argType.number];
cMINUTE.prototype.Calculate = function (arg) {
var t = this;
var bIsSpecialFunction = arguments[4];
var calculateFunc = function (curArg) {
var val;
if (curArg instanceof cArray) {
curArg = curArg.getElement(0);
} else if (curArg instanceof cArea || curArg instanceof cArea3D) {
curArg = curArg.cross(arguments[1]).tocNumber();
}
if (curArg instanceof cError) {
return curArg;
} else if (curArg instanceof cNumber || curArg instanceof cBool || curArg instanceof cEmpty) {
val = curArg.tocNumber().getValue();
} else if (curArg instanceof cRef || curArg instanceof cRef3D) {
val = curArg.getValue();
if (val instanceof cError) {
return val;
} else if (val instanceof cNumber || val instanceof cBool || curArg instanceof cEmpty) {
val = curArg.tocNumber().getValue();
} else {
return new cError(cErrorType.wrong_value_type);
}
} else if (curArg instanceof cString) {
val = curArg.tocNumber();
if (val instanceof cError || val instanceof cEmpty) {
var d = new cDate(curArg.getValue());
if (isNaN(d)) {
d = g_oFormatParser.parseDate(curArg.getValue(), AscCommon.g_oDefaultCultureInfo);
if (d == null) {
return new cError(cErrorType.wrong_value_type);
}
val = d.value;
} else {
val = (d.getTime() / 1000 - d.getTimezoneOffset() * 60) / c_sPerDay + (AscCommonExcel.c_DateCorrectConst + (AscCommon.bDate1904 ? 0 : 1));
}
} else {
val = curArg.tocNumber().getValue();
}
}
if (val < 0) {
return new cError(cErrorType.not_numeric);
} else {
//TODO исплользую функцию parseDate. по идее необходима только первая часть этой функции
d = AscCommon.NumFormat.prototype.parseDate(val);
val = d.min;
return t.setCalcValue(new cNumber(val), 0);
}
};
var arg0 = arg[0], res;
if (!bIsSpecialFunction) {
if (arg0 instanceof cArray) {
arg0 = arg0.getElement(0);
} else if (arg0 instanceof cArea || arg0 instanceof cArea3D) {
arg0 = arg0.cross(arguments[1]).tocNumber();
}
res = calculateFunc(arg0);
} else {
res = this._checkArrayArguments(arg0, calculateFunc);
}
return res;
};
/**
* @constructor
* @extends {AscCommonExcel.cBaseFunction}
*/
function cMONTH() {
}
//***array-formula***
cMONTH.prototype = Object.create(cBaseFunction.prototype);
cMONTH.prototype.constructor = cMONTH;
cMONTH.prototype.name = 'MONTH';
cMONTH.prototype.argumentsMin = 1;
cMONTH.prototype.argumentsMax = 1;
cMONTH.prototype.numFormat = AscCommonExcel.cNumFormatNone;
cMONTH.prototype.argumentsType = [argType.number];
cMONTH.prototype.Calculate = function (arg) {
let t = this;
let bIsSpecialFunction = arguments[4];
let calculateFunc = function (curArg) {
let val;
if (curArg.type === cElementType.cell || curArg.type === cElementType.cell3D) {
curArg = curArg.getValue();
}
if (curArg.type === cElementType.error) {
return curArg;
} else if (curArg.type === cElementType.number || curArg.type === cElementType.bool || curArg.type === cElementType.empty) {
val = curArg.tocNumber().getValue();
} else if (curArg.type === cElementType.string) {
val = curArg.tocNumber();
if (val.type === cElementType.error || val.type === cElementType.empty) {
let d = new cDate(curArg.getValue());
if (isNaN(d)) {
return new cError(cErrorType.wrong_value_type);
} else {
val = Math.floor((d.getTime() / 1000 - d.getTimezoneOffset() * 60) / c_sPerDay + (AscCommonExcel.c_DateCorrectConst + (AscCommon.bDate1904 ? 0 : 1)));
}
} else {
val = curArg.tocNumber().getValue();
}
}
if (val < 0) {
return new cError(cErrorType.not_numeric);
}
if (!AscCommon.bDate1904) {
if (val === 60) {
return t.setCalcValue(new cNumber(2), 0);
} else {
return t.setCalcValue(new cNumber((new cDate(((val === 0 ? 1 : val) - AscCommonExcel.c_DateCorrectConst - 1) * c_msPerDay)).getUTCMonth() + 1), 0);
}
} else {
return t.setCalcValue(new cNumber((new cDate(((val === 0 ? 1 : val) - AscCommonExcel.c_DateCorrectConst) * c_msPerDay)).getUTCMonth() + 1), 0);
}
};
let arg0 = arg[0], res;
if (!bIsSpecialFunction) {
if (arg0.type === cElementType.array) {
arg0 = arg0.getElement(0);
} else if (arg0.type === cElementType.cellsRange || arg0.type === cElementType.cellsRange3D) {
arg0 = arg0.cross(arguments[1]).tocNumber();
}
res = calculateFunc(arg0);
} else {
res = this._checkArrayArguments(arg0, calculateFunc);
}
return res;
};
/**
* @constructor
* @extends {AscCommonExcel.cBaseFunction}
*/
function cNETWORKDAYS() {
}
//***array-formula***
cNETWORKDAYS.prototype = Object.create(cBaseFunction.prototype);
cNETWORKDAYS.prototype.constructor = cNETWORKDAYS;
cNETWORKDAYS.prototype.name = 'NETWORKDAYS';
cNETWORKDAYS.prototype.argumentsMin = 2;
cNETWORKDAYS.prototype.argumentsMax = 3;
cNETWORKDAYS.prototype.numFormat = AscCommonExcel.cNumFormatNone;
cNETWORKDAYS.prototype.returnValueType = AscCommonExcel.cReturnFormulaType.value_replace_area;
cNETWORKDAYS.prototype.arrayIndexes = {2: 1};
cNETWORKDAYS.prototype.argumentsType = [argType.any, argType.any, argType.any];
cNETWORKDAYS.prototype.Calculate = function (arg) {
let oArguments = this._prepareArguments([arg[0], arg[1]], arguments[1]);
let argClone = oArguments.args;
let arg0 = arg[0],
arg1 = arg[1],
arg2 = arg[2];
// arg0 type check
if (cElementType.cell === arg0.type || cElementType.cell3D === arg0.type) {
arg0 = arg0.getValue();
} else if (cElementType.cellsRange === arg0.type || cElementType.cellsRange3D === arg0.type) {
if (arg0.isOneElement()) {
arg0 = arg0.getFirstElement();
} else {
return new cError(cErrorType.wrong_value_type);
}
} else if (cElementType.array === arg0.type) {
arg0 = arg0.getElementRowCol(0, 0);
}
if (cElementType.bool === arg0.type) {
arg0 = new cError(cErrorType.wrong_value_type);
} else if (cElementType.empty === arg0.type) {
arg0 = new cNumber(0);
}
// arg1 type check
if (cElementType.cell === arg1.type || cElementType.cell3D === arg1.type) {
arg1 = arg1.getValue();
} else if (cElementType.cellsRange === arg1.type || cElementType.cellsRange3D === arg1.type) {
if (arg1.isOneElement()) {
arg1 = arg1.getFirstElement();
} else {
return new cError(cErrorType.wrong_value_type);
}
} else if (cElementType.array === arg1.type) {
arg1 = arg1.getElementRowCol(0, 0);
}
if (cElementType.bool === arg1.type) {
arg1 = new cError(cErrorType.wrong_value_type);
} else if (cElementType.empty === arg1.type) {
arg1 = new cNumber(0);
}
arg0 = arg0.tocNumber();
arg1 = arg1.tocNumber();
if (cElementType.error === arg0.type) {
return arg0;
}
if (cElementType.error === arg1.type) {
return arg1;
}
let val0 = Math.trunc(arg0.getValue()), val1 = Math.trunc(arg1.getValue());
if (val0 < 0 || val1 < 0) {
return new cError(cErrorType.not_numeric);
} else if (val0 === 0 && val1 === 0) {
return new cNumber(0);
}
let argError;
if (argError = this._checkErrorArg(argClone)) {
return argError;
}
//function weekday also don't separate < 60
val0 = getCorrectDate2(val0);
val1 = getCorrectDate2(val1);
//Holidays
let holidays = getHolidays(arg2);
if (holidays.type === cElementType.error) {
return holidays;
}
const calcDate = function () {
let count = 0;
let start = val0;
let end = val1;
let dif = val1 - val0;
if (dif < 0) {
start = val1;
end = val0;
}
let difAbs = (end - start);
difAbs = (difAbs + (c_msPerDay)) / c_msPerDay;
for (let i = 0; i < difAbs; i++) {
let date = new cDate(start);
date.setUTCDate(Date.prototype.getUTCDate.call(start) + i);
if (date.getUTCDay() !== 6 && date.getUTCDay() !== 0 && !_includeInHolidays(date, holidays)) {
count++;
}
}
return new cNumber((dif < 0 ? -1 : 1) * count);
};
return calcDate();
};
/**
* @constructor
* @extends {AscCommonExcel.cBaseFunction}
*/
function cNETWORKDAYS_INTL() {
}
//***array-formula***
cNETWORKDAYS_INTL.prototype = Object.create(cBaseFunction.prototype);
cNETWORKDAYS_INTL.prototype.constructor = cNETWORKDAYS_INTL;
cNETWORKDAYS_INTL.prototype.name = 'NETWORKDAYS.INTL';
cNETWORKDAYS_INTL.prototype.argumentsMin = 2;
cNETWORKDAYS_INTL.prototype.argumentsMax = 4;
cNETWORKDAYS_INTL.prototype.numFormat = AscCommonExcel.cNumFormatNone;
cNETWORKDAYS_INTL.prototype.arrayIndexes = {2: 1, 3: 1};
cNETWORKDAYS_INTL.prototype.argumentsType = [argType.any, argType.any, argType.number, argType.any];
//TODO в данном случае есть различия с ms. при 3 и 4 аргументах - замена результата на ошибку не происходит.
cNETWORKDAYS_INTL.prototype.returnValueType = AscCommonExcel.cReturnFormulaType.value_replace_area;
cNETWORKDAYS_INTL.prototype.Calculate = function (arg) {
var tempArgs = arg[2] ? [arg[0], arg[1], arg[2]] : [arg[0], arg[1]];
var oArguments = this._prepareArguments(tempArgs, arguments[1]);
var argClone = oArguments.args;
argClone[0] = argClone[0].tocNumber();
argClone[1] = argClone[1].tocNumber();
var argError;
if (argError = this._checkErrorArg(argClone)) {
return argError;
}
var arg0 = argClone[0], arg1 = argClone[1], arg2 = argClone[2], arg3 = arg[3];
var val0 = arg0.getValue(), val1 = arg1.getValue();
if (val0 < 0) {
return new cError(cErrorType.not_numeric);
}
if (val1 < 0) {
return new cError(cErrorType.not_numeric);
}
val0 = getCorrectDate(val0);
val1 = getCorrectDate(val1);
//Weekend
var weekends = getWeekends(arg2);
if (weekends instanceof cError) {
return weekends;
}
//Holidays
var holidays = getHolidays(arg3);
if (holidays instanceof cError) {
return holidays;
}
var calcDate = function () {
var count = 0;
var start = val0;
var end = val1;
var dif = val1 - val0;
if (dif < 0) {
start = val1;
end = val0;
}
var difAbs = (end - start);
difAbs = (difAbs + (c_msPerDay)) / c_msPerDay;
var date = new cDate(start);
var startTime = date.getTime();
var startDay = date.getUTCDay();
for (var i = 0; i < difAbs; i++) {
if (!weekends[startDay] && !_includeInHolidaysTime(startTime, holidays)) {
count++;
}
startDay = (startDay + 1) % 7;
startTime += AscCommonExcel.c_msPerDay;
// date.setTime(startTime + i * AscCommonExcel.c_msPerDay);
//
// if (!_includeInHolidays(date, holidays) && !weekends[date.getUTCDay()]) {
// count++;
// }
}
return new cNumber((dif < 0 ? -1 : 1) * count);
};
return calcDate();
};
/**
* @constructor
* @extends {AscCommonExcel.cBaseFunction}
*/
function cNOW() {
}
//***array-formula***
cNOW.prototype = Object.create(cBaseFunction.prototype);
cNOW.prototype.constructor = cNOW;
cNOW.prototype.name = 'NOW';
cNOW.prototype.argumentsMax = 0;
cNOW.prototype.ca = true;
cNOW.prototype.argumentsType = null;
cNOW.prototype.Calculate = function () {
var d = new cDate();
var res =
new cNumber(d.getExcelDate(true) + (d.getHours() * 60 * 60 + d.getMinutes() * 60 + d.getSeconds()) / c_sPerDay);
res.numFormat = 22;
return res;
};
/**
* @constructor
* @extends {AscCommonExcel.cBaseFunction}
*/
function cSECOND() {
}
//***array-formula***
cSECOND.prototype = Object.create(cBaseFunction.prototype);
cSECOND.prototype.constructor = cSECOND;
cSECOND.prototype.name = 'SECOND';
cSECOND.prototype.argumentsMin = 1;
cSECOND.prototype.argumentsMax = 1;
cSECOND.prototype.numFormat = AscCommonExcel.cNumFormatNone;
cSECOND.prototype.argumentsType = [argType.number];
cSECOND.prototype.Calculate = function (arg) {
var t = this;
var bIsSpecialFunction = arguments[4];
var calculateFunc = function (curArg) {
var val;
if (curArg instanceof cArray) {
curArg = curArg.getElement(0);
} else if (curArg instanceof cArea || curArg instanceof cArea3D) {
curArg = curArg.cross(arguments[1]).tocNumber();
}
if (curArg instanceof cError) {
return curArg;
} else if (curArg instanceof cNumber || curArg instanceof cBool || curArg instanceof cEmpty) {
val = curArg.tocNumber().getValue();
} else if (curArg instanceof cRef || curArg instanceof cRef3D) {
val = curArg.getValue();
if (val instanceof cError) {
return val;
} else if (val instanceof cNumber || val instanceof cBool || curArg instanceof cEmpty) {
val = curArg.tocNumber().getValue();
} else {
return new cError(cErrorType.wrong_value_type);
}
} else if (curArg instanceof cString) {
val = curArg.tocNumber();
if (val instanceof cError || val instanceof cEmpty) {
var d = new cDate(curArg.getValue());
if (isNaN(d)) {
d = g_oFormatParser.parseDate(curArg.getValue(), AscCommon.g_oDefaultCultureInfo);
if (d == null) {
return new cError(cErrorType.wrong_value_type);
}
val = d.value;
} else {
val = (d.getTime() / 1000 - d.getTimezoneOffset() * 60) / c_sPerDay +
(AscCommonExcel.c_DateCorrectConst + (AscCommon.bDate1904 ? 0 : 1));
}
} else {
val = curArg.tocNumber().getValue();
}
}
if (val < 0) {
return new cError(cErrorType.not_numeric);
} else {
//val = parseInt((( val * 24 * 60 - Math.floor(val * 24 * 60) ) * 60).toFixed(cExcelDateTimeDigits)) % 60;
val = Math.floor((val * c_sPerDay + 0.5).toFixed(cExcelDateTimeDigits)) % 60;
return t.setCalcValue(new cNumber(val), 0);
}
};
var arg0 = arg[0], res;
if (!bIsSpecialFunction) {
if (arg0 instanceof cArray) {
arg0 = arg0.getElement(0);
} else if (arg0 instanceof cArea || arg0 instanceof cArea3D) {
arg0 = arg0.cross(arguments[1]).tocNumber();
}
res = calculateFunc(arg0);
} else {
res = this._checkArrayArguments(arg0, calculateFunc);
}
return res;
};
/**
* @constructor
* @extends {AscCommonExcel.cBaseFunction}
*/
function cTIME() {
}
//***array-formula***
cTIME.prototype = Object.create(cBaseFunction.prototype);
cTIME.prototype.constructor = cTIME;
cTIME.prototype.name = 'TIME';
cTIME.prototype.argumentsMin = 3;
cTIME.prototype.argumentsMax = 3;
cTIME.prototype.argumentsType = [argType.number, argType.number, argType.number];
cTIME.prototype.Calculate = function (arg) {
var hour = arg[0], minute = arg[1], second = arg[2];
if (hour instanceof cArea || hour instanceof cArea3D) {
hour = hour.cross(arguments[1]);
} else if (hour instanceof cArray) {
hour = hour.getElement(0);
}
if (minute instanceof cArea || minute instanceof cArea3D) {
minute = minute.cross(arguments[1]);
} else if (minute instanceof cArray) {
minute = minute.getElement(0);
}
if (second instanceof cArea || second instanceof cArea3D) {
second = second.cross(arguments[1]);
} else if (second instanceof cArray) {
second = second.getElement(0);
}
hour = hour.tocNumber();
minute = minute.tocNumber();
second = second.tocNumber();
if (hour instanceof cError) {
return hour;
}
if (minute instanceof cError) {
return minute;
}
if (second instanceof cError) {
return second;
}
//LO - не округляет. ms - округляет.
hour = parseInt(hour.getValue());
minute = parseInt(minute.getValue());
second = parseInt(second.getValue());
var v = (hour * 60 * 60 + minute * 60 + second) / c_sPerDay;
if (v < 0) {
return new cError(cErrorType.not_numeric);
}
var res = new cNumber(v - Math.floor(v));
res.numFormat = 18;
return res;
};
/**
* @constructor
* @extends {AscCommonExcel.cBaseFunction}
*/
function cTIMEVALUE() {
}
//***array-formula***
cTIMEVALUE.prototype = Object.create(cBaseFunction.prototype);
cTIMEVALUE.prototype.constructor = cTIMEVALUE;
cTIMEVALUE.prototype.name = 'TIMEVALUE';
cTIMEVALUE.prototype.argumentsMin = 1;
cTIMEVALUE.prototype.argumentsMax = 1;
cTIMEVALUE.prototype.numFormat = AscCommonExcel.cNumFormatNone;
cTIMEVALUE.prototype.argumentsType = [argType.number];
cTIMEVALUE.prototype.Calculate = function (arg) {
var arg0 = arg[0];
if (arg0 instanceof cArea || arg0 instanceof cArea3D) {
arg0 = arg0.cross(arguments[1]);
} else if (arg0 instanceof cArray) {
arg0 = arg0.getElementRowCol(0, 0);
}
arg0 = arg0.tocString();
if (arg0 instanceof cError) {
return arg0;
}
var res = g_oFormatParser.parse(arg0.getValue());
if (res && res.bDateTime) {
return new cNumber(res.value - parseInt(res.value));
} else {
return new cError(cErrorType.wrong_value_type);
}
};
/**
* @constructor
* @extends {AscCommonExcel.cBaseFunction}
*/
function cTODAY() {
}
//***array-formula***
cTODAY.prototype = Object.create(cBaseFunction.prototype);
cTODAY.prototype.constructor = cTODAY;
cTODAY.prototype.name = 'TODAY';
cTODAY.prototype.argumentsMax = 0;
cTODAY.prototype.ca = true;
cTODAY.prototype.argumentsType = null;
cTODAY.prototype.Calculate = function () {
var res = new cNumber(new cDate().getExcelDate(true));
res.numFormat = 14;
return res;
};
/**
* @constructor
* @extends {AscCommonExcel.cBaseFunction}
*/
function cWEEKDAY() {
}
//***array-formula***
cWEEKDAY.prototype = Object.create(cBaseFunction.prototype);
cWEEKDAY.prototype.constructor = cWEEKDAY;
cWEEKDAY.prototype.name = 'WEEKDAY';
cWEEKDAY.prototype.argumentsMin = 1;
cWEEKDAY.prototype.argumentsMax = 2;
cWEEKDAY.prototype.numFormat = AscCommonExcel.cNumFormatNone;
cWEEKDAY.prototype.argumentsType = [argType.number, argType.number];
cWEEKDAY.prototype.Calculate = function (arg) {
var arg0 = arg[0], arg1 = arg[1] ? arg[1] : new cNumber(1);
if (arg0 instanceof cArea || arg0 instanceof cArea3D) {
arg0 = arg0.cross(arguments[1]);
} else if (arg0 instanceof cArray) {
arg0 = arg0.getElementRowCol(0, 0);
}
if (arg1 instanceof cArea || arg1 instanceof cArea3D) {
arg1 = arg1.cross(arguments[1]);
} else if (arg1 instanceof cArray) {
arg1 = arg1.getElementRowCol(0, 0);
}
arg0 = arg0.tocNumber();
arg1 = arg1.tocNumber();
if (arg0 instanceof cError) {
return arg0;
}
if (arg1 instanceof cError) {
return arg1;
}
var weekday;
switch (arg1.getValue()) {
case 1: /* 1 (Sunday) through 7 (Saturday) */
case 17:/* 1 (Sunday) through 7 (Saturday) */
weekday = [1, 2, 3, 4, 5, 6, 7];
break;
case 2: /* 1 (Monday) through 7 (Sunday) */
case 11:/* 1 (Monday) through 7 (Sunday) */
weekday = [7, 1, 2, 3, 4, 5, 6];
break;
case 3: /* 0 (Monday) through 6 (Sunday) */
weekday = [6, 0, 1, 2, 3, 4, 5];
break;
case 12:/* 1 (Tuesday) through 7 (Monday) */
weekday = [6, 7, 1, 2, 3, 4, 5];
break;
case 13:/* 1 (Wednesday) through 7 (Tuesday) */
weekday = [5, 6, 7, 1, 2, 3, 4];
break;
case 14:/* 1 (Thursday) through 7 (Wednesday) */
weekday = [4, 5, 6, 7, 1, 2, 3];
break;
case 15:/* 1 (Friday) through 7 (Thursday) */
weekday = [3, 4, 5, 6, 7, 1, 2];
break;
case 16:/* 1 (Saturday) through 7 (Friday) */
weekday = [2, 3, 4, 5, 6, 7, 1];
break;
default:
return new cError(cErrorType.not_numeric);
}
if (arg0.getValue() < 0) {
return new cError(cErrorType.wrong_value_type);
}
// ???
return new cNumber(
weekday[new cDate((arg0.getValue() - (AscCommonExcel.c_DateCorrectConst + (AscCommon.bDate1904 ? 0 : 1))) * c_msPerDay).getUTCDay()]);
};
/**
* @constructor
* @extends {AscCommonExcel.cBaseFunction}
*/
function cWEEKNUM() {
}
//***array-formula***
cWEEKNUM.prototype = Object.create(cBaseFunction.prototype);
cWEEKNUM.prototype.constructor = cWEEKNUM;
cWEEKNUM.prototype.name = 'WEEKNUM';
cWEEKNUM.prototype.argumentsMin = 1;
cWEEKNUM.prototype.argumentsMax = 2;
cWEEKNUM.prototype.numFormat = AscCommonExcel.cNumFormatNone;
cWEEKNUM.prototype.returnValueType = AscCommonExcel.cReturnFormulaType.value_replace_area;
cWEEKNUM.prototype.argumentsType = [argType.any, argType.any];
cWEEKNUM.prototype.Calculate = function (arg) {
var arg0 = arg[0], arg1 = arg[1] ? arg[1] : new cNumber(1), type = 0;
if (arg0 instanceof cArea || arg0 instanceof cArea3D) {
arg0 = arg0.cross(arguments[1]);
} else if (arg0 instanceof cArray) {
arg0 = arg0.getElementRowCol(0, 0);
}
if (arg1 instanceof cArea || arg1 instanceof cArea3D) {
arg1 = arg1.cross(arguments[1]);
} else if (arg1 instanceof cArray) {
arg1 = arg1.getElementRowCol(0, 0);
}
arg0 = arg0.tocNumber();
arg1 = arg1.tocNumber();
if (arg0 instanceof cError) {
return arg0;
}
if (arg1 instanceof cError) {
return arg1;
}
if (arg0.getValue() < 0) {
return new cError(cErrorType.not_numeric);
}
var weekdayStartDay;
switch (arg1.getValue()) {
case 1: /* 1 (Sunday) through 7 (Saturday) */
case 17:/* 1 (Sunday) through 7 (Saturday) */
weekdayStartDay = [0, 1, 2, 3, 4, 5, 6];
break;
case 2: /* 1 (Monday) through 7 (Sunday) */
case 11:/* 1 (Monday) through 7 (Sunday) */
weekdayStartDay = [6, 0, 1, 2, 3, 4, 5];
break;
case 12:/* 1 (Tuesday) through 7 (Monday) */
weekdayStartDay = [5, 6, 0, 1, 2, 3, 4];
break;
case 13:/* 1 (Wednesday) through 7 (Tuesday) */
weekdayStartDay = [4, 5, 6, 0, 1, 2, 3];
break;
case 14:/* 1 (Thursday) through 7 (Wednesday) */
weekdayStartDay = [3, 4, 5, 6, 0, 1, 2];
break;
case 15:/* 1 (Friday) through 7 (Thursday) */
weekdayStartDay = [2, 3, 4, 5, 6, 0, 1];
break;
case 16:/* 1 (Saturday) through 7 (Friday) */
weekdayStartDay = [1, 2, 3, 4, 5, 6, 0];
break;
case 21:
weekdayStartDay = [6, 7, 8, 9, 10, 4, 5];
// { 6, 7, 8, 9, 10, 4, 5 }
type = 1;
break;
default:
return new cError(cErrorType.not_numeric);
}
return new cNumber(weekNumber(cDate.prototype.getDateFromExcel(arg0.getValue()), weekdayStartDay, type));
};
/**
* @constructor
* @extends {AscCommonExcel.cBaseFunction}
*/
function cWORKDAY() {
}
//***array-formula***
cWORKDAY.prototype = Object.create(cBaseFunction.prototype);
cWORKDAY.prototype.constructor = cWORKDAY;
cWORKDAY.prototype.name = 'WORKDAY';
cWORKDAY.prototype.argumentsMin = 2;
cWORKDAY.prototype.argumentsMax = 3;
cWORKDAY.prototype.numFormat = AscCommonExcel.cNumFormatNone;
cWORKDAY.prototype.returnValueType = AscCommonExcel.cReturnFormulaType.value_replace_area;
cWORKDAY.prototype.arrayIndexes = {2: 1};
cWORKDAY.prototype.argumentsType = [argType.any, argType.any, argType.any];
cWORKDAY.prototype.Calculate = function (arg) {
var t = this;
var oArguments = this._prepareArguments([arg[0], arg[1]], arguments[1], true);
var argClone = oArguments.args;
argClone[0] = argClone[0].tocNumber();
argClone[1] = argClone[1].tocNumber();
var argError;
if (argError = this._checkErrorArg(argClone)) {
return argError;
}
var arg0 = argClone[0], arg1 = argClone[1], arg2 = arg[2];
var val0 = arg0.getValue();
if (val0 < 0) {
return new cError(cErrorType.not_numeric);
}
val0 = getCorrectDate(val0);
//Holidays
var holidays = getHolidays(arg2);
if (holidays instanceof cError) {
return holidays;
}
var calcDate = function (startdate, workdaysCount, holidays) {
workdaysCount = Math.floor(workdaysCount);
var diff = Math.sign(workdaysCount);
var daysCounter = 0;
var currentDate = new cDate(startdate);
while (daysCounter !== workdaysCount) {
currentDate = new cDate(currentDate.getTime() + diff * c_msPerDay);
//TODO поверить когда переходим через argVal0 = 60
var dayOfWeek;
var argVal0 = argClone && argClone[0] ? argClone[0].getValue() : null;
if (argVal0 !== null && argVal0 < 60) {
dayOfWeek = (currentDate.getUTCDay() > 0) ? currentDate.getUTCDay() - 1 : 6;
} else {
dayOfWeek = currentDate.getUTCDay();
}
if (dayOfWeek !== 0 && dayOfWeek !== 6 && !_includeInHolidays(currentDate, holidays)) {
daysCounter += diff;
}
}
return currentDate;
};
if (undefined === arg1.getValue()) {
return new cError(cErrorType.not_numeric);
}
var date = calcDate(val0, arg1.getValue(), holidays);
var val = date.getExcelDate();
if (val < 0) {
return new cError(cErrorType.not_numeric);
}
return t.setCalcValue(new cNumber(val), 14);
};
/**
* @constructor
* @extends {AscCommonExcel.cBaseFunction}
*/
function cWORKDAY_INTL() {
}
//***array-formula***
cWORKDAY_INTL.prototype = Object.create(cBaseFunction.prototype);
cWORKDAY_INTL.prototype.constructor = cWORKDAY_INTL;
cWORKDAY_INTL.prototype.name = 'WORKDAY.INTL';
cWORKDAY_INTL.prototype.argumentsMin = 2;
cWORKDAY_INTL.prototype.argumentsMax = 4;
cWORKDAY_INTL.prototype.numFormat = AscCommonExcel.cNumFormatNone;
cWORKDAY_INTL.prototype.arrayIndexes = {0: AscCommonExcel.arrayIndexesType.range, 1: AscCommonExcel.arrayIndexesType.range, 3: 1};
cWORKDAY_INTL.prototype.argumentsType = [argType.any, argType.any, argType.number, argType.any];
//TODO в данном случае есть различия с ms. при 3 и 4 аргументах - замена результата на ошибку не происходит.
// cWORKDAY_INTL.prototype.returnValueType = AscCommonExcel.cReturnFormulaType.value_replace_area;
cWORKDAY_INTL.prototype.Calculate = function (arg) {
//TODO проблема с формулами следующего типа - WORKDAY.INTL(8,60,"0000000")
let t = this;
let tempArgs = arg[2] ? [arg[0], arg[1], arg[2]] : [arg[0], arg[1]];
let oArguments = this._prepareArguments(tempArgs, arguments[1]);
let argClone = oArguments.args;
if ((arg[0] && (arg[0].type === cElementType.cellsRange || arg[0].type === cElementType.cellsRange3D)) ||
(arg[1] && (arg[1].type === cElementType.cellsRange || arg[1].type === cElementType.cellsRange3D))) {
return new cError(cErrorType.wrong_value_type);
}
argClone[0] = argClone[0].tocNumber();
argClone[1] = argClone[1].tocNumber();
let argError;
if (argError = this._checkErrorArg(argClone)) {
return argError;
}
let arg0 = argClone[0], arg1 = argClone[1], arg2 = argClone[2], arg3 = arg[3];
let val0 = arg0.getValue();
if (val0 < 0) {
return new cError(cErrorType.not_numeric);
}
val0 = val0 < 61 ? new cDate((val0 - (AscCommonExcel.c_DateCorrectConst + (AscCommon.bDate1904 ? 0 : 1))) * c_msPerDay) : getCorrectDate(val0);
// Weekend
if (arg2 && "1111111" === arg2.getValue()) {
return new cError(cErrorType.wrong_value_type);
}
let weekends = getWeekends(arg2);
if (weekends instanceof cError) {
return weekends;
}
// Holidays
let holidays = getHolidays(arg3);
if (holidays instanceof cError) {
return holidays;
}
const calcDate = function () {
let dif = arg1.getValue(), count = 0, dif1 = dif > 0 ? 1 : dif < 0 ? -1 : 0, val, date = val0,
isEndOfCycle = false;
while (Math.abs(dif) > count) {
date = new cDate(val0.getTime() + dif1 * c_msPerDay);
if (!_includeInHolidays(date, holidays) && !weekends[date.getUTCDay()]) {
count++;
}
// if last iteration:
if (!(Math.abs(dif) > count)) {
// check if it's next weekend. if found - add
date = new cDate(val0.getTime() + dif1 * c_msPerDay);
for (let i = 0; i < 7; i++) {
if (weekends[date.getUTCDay()]) {
dif >= 0 ? dif1++ : dif1--;
date = new cDate(val0.getTime() + (dif1) * c_msPerDay);
} else {
isEndOfCycle = true;
break;
}
}
}
!isEndOfCycle ? (dif >= 0 ? dif1++ : dif1--) : null;
}
date = new cDate(val0.getTime() + dif1 * c_msPerDay);
val = date.getExcelDate();
if (val < 0) {
return new cError(cErrorType.not_numeric);
}
// shift for date less than 1/3/1900
if (arg0.getValue() < 61) {
val++;
}
return t.setCalcValue(new cNumber(val), 14);
};
return calcDate();
};
/**
* @constructor
* @extends {AscCommonExcel.cBaseFunction}
*/
function cYEAR() {
}
//***array-formula***
cYEAR.prototype = Object.create(cBaseFunction.prototype);
cYEAR.prototype.constructor = cYEAR;
cYEAR.prototype.name = 'YEAR';
cYEAR.prototype.argumentsMin = 1;
cYEAR.prototype.argumentsMax = 1;
cYEAR.prototype.numFormat = AscCommonExcel.cNumFormatNone;
cYEAR.prototype.argumentsType = [argType.number];
cYEAR.prototype.Calculate = function (arg) {
let t = this;
let bIsSpecialFunction = arguments[4];
let calculateFunc = function (curArg) {
let val;
if (curArg.type === cElementType.cell || curArg.type === cElementType.cell3D) {
curArg = curArg.getValue();
}
if (curArg.type === cElementType.error) {
return curArg;
} else if (curArg.type === cElementType.number || curArg.type === cElementType.bool || curArg.type === cElementType.empty) {
val = curArg.tocNumber().getValue();
} else if (curArg.type === cElementType.cellsRange || curArg.type === cElementType.cellsRange3D) {
return new cError(cErrorType.wrong_value_type);
} else if (curArg.type === cElementType.string) {
val = curArg.tocNumber();
if (val.type === cElementType.error || val.type === cElementType.empty) {
let d = new cDate(curArg.getValue());
if (isNaN(d)) {
return new cError(cErrorType.wrong_value_type);
} else {
val = Math.floor((d.getTime() / 1000 - d.getTimezoneOffset() * 60) / c_sPerDay + (AscCommonExcel.c_DateCorrectConst + (AscCommon.bDate1904 ? 0 : 1)));
}
} else {
val = curArg.tocNumber().getValue();
}
}
if (val < 0) {
return t.setCalcValue(new cError(cErrorType.not_numeric), 0);
} else {
if (AscCommon.bDate1904 && val === 0) {
val += 1;
}
return t.setCalcValue(new cNumber((new cDate((val - (AscCommonExcel.c_DateCorrectConst + 1)) * c_msPerDay)).getUTCFullYear()), 0);
}
};
let arg0 = arg[0], res;
if (!bIsSpecialFunction) {
if (arg0.type === cElementType.array) {
arg0 = arg0.getElement(0);
} else if (arg0.type === cElementType.cellsRange || arg0.type === cElementType.cellsRange3D) {
arg0 = arg0.cross(arguments[1]).tocNumber();
}
res = calculateFunc(arg0);
} else {
res = this._checkArrayArguments(arg0, calculateFunc);
}
return res;
};
/**
* @constructor
* @extends {AscCommonExcel.cBaseFunction}
*/
function cYEARFRAC() {
}
//***array-formula***
cYEARFRAC.prototype = Object.create(cBaseFunction.prototype);
cYEARFRAC.prototype.constructor = cYEARFRAC;
cYEARFRAC.prototype.name = 'YEARFRAC';
cYEARFRAC.prototype.argumentsMin = 2;
cYEARFRAC.prototype.argumentsMax = 3;
cYEARFRAC.prototype.numFormat = AscCommonExcel.cNumFormatNone;
cYEARFRAC.prototype.returnValueType = AscCommonExcel.cReturnFormulaType.value_replace_area;
cYEARFRAC.prototype.argumentsType = [argType.any, argType.any, argType.any];
cYEARFRAC.prototype.Calculate = function (arg) {
var arg0 = arg[0], arg1 = arg[1], arg2 = arg[2] ? arg[2] : new cNumber(0);
if (arg0 instanceof cArea || arg0 instanceof cArea3D) {
arg0 = arg0.cross(arguments[1]);
} else if (arg0 instanceof cArray) {
arg0 = arg0.getElementRowCol(0, 0);
}
if (arg1 instanceof cArea || arg1 instanceof cArea3D) {
arg1 = arg1.cross(arguments[1]);
} else if (arg1 instanceof cArray) {
arg1 = arg1.getElementRowCol(0, 0);
}
if (arg2 instanceof cArea || arg2 instanceof cArea3D) {
arg2 = arg2.cross(arguments[1]);
} else if (arg2 instanceof cArray) {
arg2 = arg2.getElementRowCol(0, 0);
}
arg0 = arg0.tocNumber();
arg1 = arg1.tocNumber();
arg2 = arg2.tocNumber();
if (arg0 instanceof cError) {
return arg0;
}
if (arg1 instanceof cError) {
return arg1;
}
if (arg2 instanceof cError) {
return arg2;
}
var val0 = arg0.getValue(), val1 = arg1.getValue();
if (val0 < 0 || val1 < 0) {
return new cError(cErrorType.not_numeric);
}
val0 = cDate.prototype.getDateFromExcel(val0);
val1 = cDate.prototype.getDateFromExcel(val1);
return yearFrac(val0, val1, arg2.getValue());
// return diffDate2( val0, val1, arg2.getValue() );
};
//----------------------------------------------------------export----------------------------------------------------
window['AscCommonExcel'] = window['AscCommonExcel'] || {};
window['AscCommonExcel'].DayCountBasis = DayCountBasis;
window['AscCommonExcel'].yearFrac = yearFrac;
window['AscCommonExcel'].diffDate = diffDate;
window['AscCommonExcel'].days360 = days360;
window['AscCommonExcel'].getCorrectDate = getCorrectDate;
window['AscCommonExcel'].daysInYear = daysInYear;
window['AscCommonExcel'].getLastDayInMonth = getLastDayInMonth;
})(window);