/* * (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);