DocumentServer/OfficeWeb/sdk/Excel/model/FormulaObjects/dateandtimeFunctions.js
nikolay ivanov a8be6b9e72 init repo
2014-07-05 18:22:49 +00:00

1545 lines
61 KiB
JavaScript

/*
* (c) Copyright Ascensio System SIA 2010-2014
*
* 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 Lubanas st. 125a-25, Riga, Latvia,
* EU, LV-1021.
*
* 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
*
*/
function GetDiffDate360(nDay1, nMonth1, nYear1, bLeapYear1, nDay2, nMonth2, nYear2, bUSAMethod) {
if (nDay1 == 31) {
nDay1--;
} else {
if (bUSAMethod && (nMonth1 == 2 && (nDay1 == 29 || (nDay1 == 28 && !bLeapYear1)))) {
nDay1 = 30;
}
}
if (nDay2 == 31) {
if (bUSAMethod && nDay1 != 30) {
nDay2 = 1;
if (nMonth2 == 12) {
nYear2++;
nMonth2 = 1;
} else {
nMonth2++;
}
} else {
nDay2 = 30;
}
}
return nDay2 + nMonth2 * 30 + nYear2 * 360 - nDay1 - nMonth1 * 30 - nYear1 * 360;
}
cFormulaFunction.DateAndTime = {
"groupName": "DateAndTime",
"DATE": function () {
var r = new cBaseFunction("DATE");
r.setArgumentsMin(3);
r.setArgumentsMax(3);
r.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].first);
} else {
if (arg0 instanceof cArray) {
arg0 = arg0.getElement(0);
}
}
if (arg1 instanceof cArea || arg1 instanceof cArea3D) {
arg1 = arg1.cross(arguments[1].first);
} else {
if (arg1 instanceof cArray) {
arg1 = arg1.getElement(0);
}
}
if (arg2 instanceof cArea || arg2 instanceof cArea3D) {
arg2 = arg2.cross(arguments[1].first);
} else {
if (arg2 instanceof cArray) {
arg2 = arg2.getElement(0);
}
}
arg0 = arg0.tocNumber();
arg1 = arg1.tocNumber();
arg2 = arg2.tocNumber();
if (arg0 instanceof cError) {
return this.setCA(arg0, true);
}
if (arg1 instanceof cError) {
return this.setCA(arg1, true);
}
if (arg2 instanceof cError) {
return this.setCA(arg2, true);
}
year = arg0.getValue();
month = arg1.getValue();
day = arg2.getValue();
if (year >= 0 && year <= 1899) {
year += 1900;
}
if (month == 0) {
return this.setCA(new cError(cErrorType.not_numeric), true);
}
this.value = new cNumber(Math.round(new Date(year, month - 1, day).getExcelDate()));
this.value.numFormat = 14;
this.value.ca = true;
return this.value;
};
r.getInfo = function () {
return {
name: this.name,
args: "( year, month, day )"
};
};
return r;
},
"DATEDIF": function () {
var r = new cBaseFunction("DATEDIF");
r.setArgumentsMin(3);
r.setArgumentsMax(3);
r.Calculate = function (arg) {
var arg0 = arg[0],
arg1 = arg[1],
arg2 = arg[2];
if (arg0 instanceof cArea || arg0 instanceof cArea3D) {
arg0 = arg0.cross(arguments[1].first);
} else {
if (arg0 instanceof cArray) {
arg0 = arg0.getElementRowCol(0, 0);
}
}
if (arg1 instanceof cArea || arg1 instanceof cArea3D) {
arg1 = arg1.cross(arguments[1].first);
} else {
if (arg1 instanceof cArray) {
arg1 = arg1.getElementRowCol(0, 0);
}
}
if (arg2 instanceof cArea || arg2 instanceof cArea3D) {
arg2 = arg2.cross(arguments[1].first);
} else {
if (arg2 instanceof cArray) {
arg2 = arg2.getElementRowCol(0, 0);
}
}
arg0 = arg0.tocNumber();
arg1 = arg1.tocNumber();
arg2 = arg2.tocString();
if (arg0 instanceof cError) {
return this.value = arg0;
}
if (arg1 instanceof cError) {
return this.value = arg1;
}
if (arg2 instanceof cError) {
return this.value = arg2;
}
var val0 = arg0.getValue(),
val1 = arg1.getValue();
if (val0 < 0 || val1 < 0 || val0 >= val1) {
return this.setCA(new cError(cErrorType.not_numeric), true);
}
val0 = Date.prototype.getDateFromExcel(val0);
val1 = Date.prototype.getDateFromExcel(val1);
function dateDiff(date1, date2) {
var years = date2.getFullYear() - date1.getFullYear();
var months = years * 12 + date2.getMonth() - date1.getMonth();
var days = date2.getDate() - date1.getDate();
years -= date2.getMonth() < date1.getMonth();
months -= date2.getDate() < date1.getDate();
days += days < 0 ? new Date(date2.getFullYear(), date2.getMonth() - 1, 0).getDate() + 1 : 0;
return [years, months, days];
}
switch (arg2.getValue().toUpperCase()) {
case "Y":
return this.value = new cNumber(dateDiff(val0, val1)[0]);
break;
case "M":
return this.value = new cNumber(dateDiff(val0, val1)[1]);
break;
case "D":
return this.value = new cNumber(parseInt((val1 - val0) / c_msPerDay));
break;
case "MD":
if (val0.getDate() > val1.getDate()) {
this.value = new cNumber(Math.abs(new Date(val0.getFullYear(), val0.getMonth(), val0.getDate()) - new Date(val0.getFullYear(), val0.getMonth() + 1, val1.getDate())) / c_msPerDay);
} else {
this.value = new cNumber(val1.getDate() - val0.getDate());
}
return this.value;
break;
case "YM":
var d = dateDiff(val0, val1);
return this.value = new cNumber(d[1] - d[0] * 12);
break;
case "YD":
if (val0.getMonth() > val1.getMonth()) {
this.value = new cNumber(Math.abs(new Date(val0.getFullYear(), val0.getMonth(), val0.getDate()) - new Date(val0.getFullYear() + 1, val1.getMonth(), val1.getDate())) / c_msPerDay);
} else {
this.value = new cNumber(Math.abs(new Date(val0.getFullYear(), val0.getMonth(), val0.getDate()) - new Date(val0.getFullYear(), val1.getMonth(), val1.getDate())) / c_msPerDay);
}
return this.value;
break;
default:
return this.value = new cError(cErrorType.not_numeric);
}
};
r.getInfo = function () {
return {
name: this.name,
args: "( start-date , end-date , unit )"
};
};
r.setFormat(r.formatType.noneFormat);
return r;
},
"DATEVALUE": function () {
var r = new cBaseFunction("DATEVALUE");
r.setArgumentsMin(1);
r.setArgumentsMax(1);
r.Calculate = function (arg) {
var arg0 = arg[0];
if (arg0 instanceof cArea || arg0 instanceof cArea3D) {
arg0 = arg0.cross(arguments[1].first);
} else {
if (arg0 instanceof cArray) {
arg0 = arg0.getElementRowCol(0, 0);
}
}
arg0 = arg0.tocString();
if (arg0 instanceof cError) {
return this.value = arg0;
}
if (arg0.tocNumber() instanceof cNumber && arg0.tocNumber().getValue() > 0) {
return this.value = new cNumber(parseInt(arg0.tocNumber().getValue()));
}
var res = g_oFormatParser.parse(arg0.getValue());
if (res && res.bDateTime) {
return this.value = new cNumber(parseInt(res.value));
} else {
return this.value = new cError(cErrorType.wrong_value_type);
}
};
r.getInfo = function () {
return {
name: this.name,
args: "( date-time-string )"
};
};
r.setFormat(r.formatType.noneFormat);
return r;
},
"DAY": function () {
var r = new cBaseFunction("DAY");
r.setArgumentsMin(1);
r.setArgumentsMax(1);
r.Calculate = function (arg) {
var arg0 = arg[0],
val;
if (arg0 instanceof cArray) {
arg0 = arg0.getElement(0);
} else {
if (arg0 instanceof cArea || arg0 instanceof cArea3D) {
arg0 = arg0.cross(arguments[1].first).tocNumber();
val = arg0.tocNumber().getValue();
}
}
if (arg0 instanceof cError) {
return this.setCA(arg0, true);
} else {
if (arg0 instanceof cNumber || arg0 instanceof cBool) {
val = arg0.tocNumber().getValue();
} else {
if (arg0 instanceof cRef || arg0 instanceof cRef3D) {
val = arg0.getValue().tocNumber();
if (val instanceof cNumber || val instanceof cBool) {
val = arg0.tocNumber().getValue();
} else {
return this.setCA(new cError(cErrorType.wrong_value_type), true);
}
} else {
if (arg0 instanceof cString) {
val = arg0.tocNumber();
if (val instanceof cError || val instanceof cEmpty) {
var d = new Date(arg0.getValue());
if (isNaN(d)) {
return this.setCA(new cError(cErrorType.wrong_value_type), true);
} else {
val = Math.floor((d.getTime() / 1000 - d.getTimezoneOffset() * 60) / c_sPerDay + (c_DateCorrectConst + (g_bDate1904 ? 0 : 1)));
}
} else {
val = arg0.tocNumber().getValue();
}
}
}
}
}
if (val < 0) {
return this.setCA(new cError(cErrorType.not_numeric), true);
} else {
if (!g_bDate1904) {
if (val < 60) {
return this.setCA(new cNumber((new Date((val - c_DateCorrectConst) * c_msPerDay)).getUTCDate()), true, 0);
} else {
if (val == 60) {
return this.setCA(new cNumber((new Date((val - c_DateCorrectConst - 1) * c_msPerDay)).getUTCDate() + 1), true, 0);
} else {
return this.setCA(new cNumber((new Date((val - c_DateCorrectConst - 1) * c_msPerDay)).getUTCDate()), true, 0);
}
}
} else {
return this.setCA(new cNumber((new Date((val - c_DateCorrectConst) * c_msPerDay)).getUTCDate()), true, 0);
}
}
};
r.getInfo = function () {
return {
name: this.name,
args: "( date-value )"
};
};
r.setFormat(r.formatType.noneFormat);
return r;
},
"DAYS360": function () {
var r = new cBaseFunction("DAYS360");
r.setArgumentsMin(2);
r.setArgumentsMax(3);
r.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].first);
} else {
if (arg0 instanceof cArray) {
arg0 = arg0.getElementRowCol(0, 0);
}
}
if (arg1 instanceof cArea || arg1 instanceof cArea3D) {
arg1 = arg1.cross(arguments[1].first);
} else {
if (arg1 instanceof cArray) {
arg1 = arg1.getElementRowCol(0, 0);
}
}
if (arg2 instanceof cArea || arg2 instanceof cArea3D) {
arg2 = arg2.cross(arguments[1].first);
} else {
if (arg2 instanceof cArray) {
arg2 = arg2.getElementRowCol(0, 0);
}
}
arg0 = arg0.tocNumber();
arg1 = arg1.tocNumber();
arg2 = arg2.tocBool();
if (arg0 instanceof cError) {
return this.value = arg0;
}
if (arg1 instanceof cError) {
return this.value = arg1;
}
if (arg2 instanceof cError) {
return this.value = arg2;
}
if (arg0.getValue() < 0) {
return this.value = new cError(cErrorType.not_numeric);
}
if (arg1.getValue() < 0) {
return this.value = new cError(cErrorType.not_numeric);
}
var date1 = Date.prototype.getDateFromExcel(arg0.getValue()),
date2 = Date.prototype.getDateFromExcel(arg1.getValue());
return this.value = new cNumber(GetDiffDate360(date1.getDate(), date1.getMonth() + 1, date1.getFullYear(), date1.isLeapYear(), date2.getDate(), date2.getMonth() + 1, date2.getFullYear(), !arg2.toBool()));
};
r.getInfo = function () {
return {
name: this.name,
args: "( start-date , end-date [ , method-flag ] )"
};
};
r.setFormat(r.formatType.noneFormat);
return r;
},
"EDATE": function () {
var r = new cBaseFunction("EDATE");
r.setArgumentsMin(2);
r.setArgumentsMax(2);
r.Calculate = function (arg) {
var arg0 = arg[0],
arg1 = arg[1];
if (arg0 instanceof cArea || arg0 instanceof cArea3D) {
arg0 = arg0.cross(arguments[1].first);
} else {
if (arg0 instanceof cArray) {
arg0 = arg0.getElementRowCol(0, 0);
}
}
if (arg1 instanceof cArea || arg1 instanceof cArea3D) {
arg1 = arg1.cross(arguments[1].first);
} else {
if (arg1 instanceof cArray) {
arg1 = arg1.getElementRowCol(0, 0);
}
}
arg0 = arg0.tocNumber();
arg1 = arg1.tocNumber();
if (arg0 instanceof cError) {
return this.value = arg0;
}
if (arg1 instanceof cError) {
return this.value = arg1;
}
var val = arg0.getValue(),
date,
_date;
if (val < 0) {
return this.setCA(new cError(cErrorType.not_numeric), true);
} else {
if (!g_bDate1904) {
if (val < 60) {
val = new Date((val - c_DateCorrectConst) * c_msPerDay);
} else {
if (val == 60) {
val = new Date((val - c_DateCorrectConst - 1) * c_msPerDay);
} else {
val = new Date((val - c_DateCorrectConst - 1) * c_msPerDay);
}
}
} else {
val = new Date((val - c_DateCorrectConst) * c_msPerDay);
}
}
date = new Date(val);
if (0 <= date.getDate() && 28 >= date.getDate()) {
val = new Date(val.setMonth(val.getMonth() + arg1.getValue()));
} else {
if (29 <= date.getDate() && 31 >= date.getDate()) {
date.setDate(1);
date.setMonth(date.getMonth() + arg1.getValue());
if (val.getDate() > (_date = date.getDaysInMonth())) {
val.setDate(_date);
}
val = new Date(val.setMonth(val.getMonth() + arg1.getValue()));
}
}
return this.value = new cNumber(Math.floor((val.getTime() / 1000 - val.getTimezoneOffset() * 60) / c_sPerDay + (c_DateCorrectConst + 1)));
};
r.getInfo = function () {
return {
name: this.name,
args: "( start-date , month-offset )"
};
};
r.setFormat(r.formatType.noneFormat);
return r;
},
"EOMONTH": function () {
var r = new cBaseFunction("EOMONTH");
r.setArgumentsMin(2);
r.setArgumentsMax(2);
r.Calculate = function (arg) {
var arg0 = arg[0],
arg1 = arg[1];
if (arg0 instanceof cArea || arg0 instanceof cArea3D) {
arg0 = arg0.cross(arguments[1].first);
} else {
if (arg0 instanceof cArray) {
arg0 = arg0.getElementRowCol(0, 0);
}
}
if (arg1 instanceof cArea || arg1 instanceof cArea3D) {
arg1 = arg1.cross(arguments[1].first);
} else {
if (arg1 instanceof cArray) {
arg1 = arg1.getElementRowCol(0, 0);
}
}
arg0 = arg0.tocNumber();
arg1 = arg1.tocNumber();
if (arg0 instanceof cError) {
return this.value = arg0;
}
if (arg1 instanceof cError) {
return this.value = arg1;
}
var val = arg0.getValue(),
date,
_date;
if (val < 0) {
return this.setCA(new cError(cErrorType.not_numeric), true);
} else {
if (!g_bDate1904) {
if (val < 60) {
val = new Date((val - c_DateCorrectConst) * c_msPerDay);
} else {
if (val == 60) {
val = new Date((val - c_DateCorrectConst - 1) * c_msPerDay);
} else {
val = new Date((val - c_DateCorrectConst - 1) * c_msPerDay);
}
}
} else {
val = new Date((val - c_DateCorrectConst) * c_msPerDay);
}
}
date = new Date(val);
val.setDate(1);
val.setMonth(val.getMonth() + arg1.getValue());
val.setDate(val.getDaysInMonth());
return this.value = new cNumber(Math.floor((val.getTime() / 1000 - val.getTimezoneOffset() * 60) / c_sPerDay + (c_DateCorrectConst + 1)));
};
r.getInfo = function () {
return {
name: this.name,
args: "( start-date , month-offset )"
};
};
r.setFormat(r.formatType.noneFormat);
return r;
},
"HOUR": function () {
var r = new cBaseFunction("HOUR");
r.setArgumentsMin(1);
r.setArgumentsMax(1);
r.Calculate = function (arg) {
var arg0 = arg[0],
val;
if (arg0 instanceof cArray) {
arg0 = arg0.getElement(0);
} else {
if (arg0 instanceof cArea || arg0 instanceof cArea3D) {
arg0 = arg0.cross(arguments[1].first).tocNumber();
}
}
if (arg0 instanceof cError) {
return this.setCA(arg0, true);
} else {
if (arg0 instanceof cNumber || arg0 instanceof cBool) {
val = arg0.tocNumber().getValue();
} else {
if (arg0 instanceof cRef || arg0 instanceof cRef3D) {
val = arg0.getValue();
if (val instanceof cError) {
return this.setCA(val, true);
} else {
if (val instanceof cNumber || val instanceof cBool) {
val = arg0.tocNumber().getValue();
} else {
return this.setCA(new cError(cErrorType.wrong_value_type), true);
}
}
} else {
if (arg0 instanceof cString) {
val = arg0.tocNumber();
if (val instanceof cError || val instanceof cEmpty) {
var d = new Date(arg0.getValue());
if (isNaN(d)) {
d = g_oFormatParser.parseDate(arg0.getValue());
if (d == null) {
return this.setCA(new cError(cErrorType.wrong_value_type), true);
}
val = d.value;
} else {
val = (d.getTime() / 1000 - d.getTimezoneOffset() * 60) / c_sPerDay + (c_DateCorrectConst + (g_bDate1904 ? 0 : 1));
}
} else {
val = arg0.tocNumber().getValue();
}
}
}
}
}
if (val < 0) {
return this.setCA(new cError(cErrorType.not_numeric), true);
} else {
return this.setCA(new cNumber(parseInt(((val - Math.floor(val)) * 24).toFixed(cExcelDateTimeDigits))), true, 0);
}
};
r.getInfo = function () {
return {
name: this.name,
args: "( time-value )"
};
};
r.setFormat(r.formatType.noneFormat);
return r;
},
"MINUTE": function () {
var r = new cBaseFunction("MINUTE");
r.setArgumentsMin(1);
r.setArgumentsMax(1);
r.Calculate = function (arg) {
var arg0 = arg[0],
val;
if (arg0 instanceof cArray) {
arg0 = arg0.getElement(0);
} else {
if (arg0 instanceof cArea || arg0 instanceof cArea3D) {
arg0 = arg0.cross(arguments[1].first).tocNumber();
}
}
if (arg0 instanceof cError) {
return this.setCA(arg0, true);
} else {
if (arg0 instanceof cNumber || arg0 instanceof cBool) {
val = arg0.tocNumber().getValue();
} else {
if (arg0 instanceof cRef || arg0 instanceof cRef3D) {
val = arg0.getValue();
if (val instanceof cError) {
return this.setCA(val, true);
} else {
if (val instanceof cNumber || val instanceof cBool) {
val = arg0.tocNumber().getValue();
} else {
return this.setCA(new cError(cErrorType.wrong_value_type), true);
}
}
} else {
if (arg0 instanceof cString) {
val = arg0.tocNumber();
if (val instanceof cError || val instanceof cEmpty) {
var d = new Date(arg0.getValue());
if (isNaN(d)) {
d = g_oFormatParser.parseDate(arg0.getValue());
if (d == null) {
return this.setCA(new cError(cErrorType.wrong_value_type), true);
}
val = d.value;
} else {
val = (d.getTime() / 1000 - d.getTimezoneOffset() * 60) / c_sPerDay + (c_DateCorrectConst + (g_bDate1904 ? 0 : 1));
}
} else {
val = arg0.tocNumber().getValue();
}
}
}
}
}
if (val < 0) {
return this.setCA(new cError(cErrorType.not_numeric), true);
} else {
val = parseInt(((val * 24 - Math.floor(val * 24)) * 60).toFixed(cExcelDateTimeDigits)) % 60;
return this.setCA(new cNumber(val), true, 0);
}
};
r.getInfo = function () {
return {
name: this.name,
args: "( time-value )"
};
};
r.setFormat(r.formatType.noneFormat);
return r;
},
"MONTH": function () {
var r = new cBaseFunction("MONTH");
r.setArgumentsMin(1);
r.setArgumentsMax(1);
r.Calculate = function (arg) {
var arg0 = arg[0],
val;
if (arg0 instanceof cArray) {
arg0 = arg0.getElement(0);
} else {
if (arg0 instanceof cArea || arg0 instanceof cArea3D) {
arg0 = arg0.cross(arguments[1].first).tocNumber();
}
}
if (arg0 instanceof cError) {
return this.setCA(arg0, true);
} else {
if (arg0 instanceof cNumber || arg0 instanceof cBool) {
val = arg0.tocNumber().getValue();
} else {
if (arg0 instanceof cRef || arg0 instanceof cRef3D) {
val = arg0.getValue();
if (val instanceof cError) {
return this.setCA(val, true);
} else {
if (val instanceof cNumber || val instanceof cBool) {
val = arg0.tocNumber().getValue();
} else {
return this.setCA(new cError(cErrorType.wrong_value_type), true);
}
}
} else {
if (arg0 instanceof cString) {
val = arg0.tocNumber();
if (val instanceof cError || val instanceof cEmpty) {
var d = new Date(arg0.getValue());
if (isNaN(d)) {
return this.setCA(new cError(cErrorType.wrong_value_type), true);
} else {
val = Math.floor((d.getTime() / 1000 - d.getTimezoneOffset() * 60) / c_sPerDay + (c_DateCorrectConst + (g_bDate1904 ? 0 : 1)));
}
} else {
val = arg0.tocNumber().getValue();
}
}
}
}
}
if (val < 0) {
return this.setCA(new cError(cErrorType.not_numeric), true);
}
if (!g_bDate1904) {
if (val == 60) {
return this.setCA(new cNumber(2), true, 0);
} else {
return this.setCA(new cNumber((new Date(((val == 0 ? 1 : val) - c_DateCorrectConst - 1) * c_msPerDay)).getUTCMonth() + 1), true, 0);
}
} else {
return this.setCA(new cNumber((new Date(((val == 0 ? 1 : val) - c_DateCorrectConst) * c_msPerDay)).getUTCMonth() + 1), true, 0);
}
};
r.getInfo = function () {
return {
name: this.name,
args: "( date-value )"
};
};
r.setFormat(r.formatType.noneFormat);
return r;
},
"NETWORKDAYS": function () {
var r = new cBaseFunction("NETWORKDAYS");
r.setArgumentsMin(2);
r.setArgumentsMax(3);
r.Calculate = function (arg) {
var arg0 = arg[0],
arg1 = arg[1],
arg2 = arg[2],
arrDateIncl = [];
if (arg0 instanceof cArea || arg0 instanceof cArea3D) {
arg0 = arg0.cross(arguments[1].first);
} else {
if (arg0 instanceof cArray) {
arg0 = arg0.getElementRowCol(0, 0);
}
}
if (arg1 instanceof cArea || arg1 instanceof cArea3D) {
arg1 = arg1.cross(arguments[1].first);
} else {
if (arg1 instanceof cArray) {
arg1 = arg1.getElementRowCol(0, 0);
}
}
arg0 = arg0.tocNumber();
arg1 = arg1.tocNumber();
if (arg0 instanceof cError) {
return this.value = arg0;
}
if (arg1 instanceof cError) {
return this.value = arg1;
}
var val0 = arg0.getValue(),
val1 = arg1.getValue(),
dif,
count = 0;
if (val0 < 0) {
return this.setCA(new cError(cErrorType.not_numeric), true);
} else {
if (!g_bDate1904) {
if (val0 < 60) {
val0 = new Date((val0 - c_DateCorrectConst) * c_msPerDay);
} else {
if (val0 == 60) {
val0 = new Date((val0 - c_DateCorrectConst - 1) * c_msPerDay);
} else {
val0 = new Date((val0 - c_DateCorrectConst - 1) * c_msPerDay);
}
}
} else {
val0 = new Date((val0 - c_DateCorrectConst) * c_msPerDay);
}
}
if (val1 < 0) {
return this.setCA(new cError(cErrorType.not_numeric), true);
} else {
if (!g_bDate1904) {
if (val1 < 60) {
val1 = new Date((val1 - c_DateCorrectConst) * c_msPerDay);
} else {
if (val1 == 60) {
val1 = new Date((val1 - c_DateCorrectConst - 1) * c_msPerDay);
} else {
val1 = new Date((val1 - c_DateCorrectConst - 1) * c_msPerDay);
}
}
} else {
val1 = new Date((val1 - c_DateCorrectConst) * c_msPerDay);
}
}
var holidays = [];
if (arg2) {
if (arg2 instanceof cRef) {
var a = arg2.getValue();
if (a instanceof cNumber && a.getValue() >= 0) {
holidays.push(a);
}
} else {
if (arg2 instanceof cArea || arg2 instanceof cArea3D) {
var arr = arg2.getValue();
for (var i = 0; i < arr.length; i++) {
if (arr[i] instanceof cNumber && arr[i].getValue() >= 0) {
holidays.push(arr[i]);
}
}
} else {
if (arg2 instanceof cArray) {
arg2.foreach(function (elem, r, c) {
if (elem instanceof cNumber) {
holidays.push(elem);
} else {
if (elem instanceof cString) {
var res = g_oFormatParser.parse(elem.getValue());
if (res && res.bDateTime && res.value >= 0) {
holidays.push(new cNumber(parseInt(res.value)));
}
}
}
});
}
}
}
}
for (var i = 0; i < holidays.length; i++) {
holidays[i] = Date.prototype.getDateFromExcel(holidays[i].getValue());
}
function includeInHolidays(date) {
for (var i = 0; i < holidays.length; i++) {
if (date.getTime() == holidays[i].getTime()) {
return false;
}
}
return true;
}
dif = (val1 - val0);
dif = (dif + (dif >= 0 ? c_msPerDay : 0)) / c_msPerDay;
for (var i = 0; i < Math.abs(dif); i++) {
var date = new Date(val0);
date.setDate(val0.getDate() + i);
if (date.getDay() != 6 && date.getDay() != 0 && includeInHolidays(date)) {
count++;
}
}
return this.value = new cNumber((dif < 0 ? -1 : 1) * count);
};
r.getInfo = function () {
return {
name: this.name,
args: "( start-date , end-date [ , holidays ] )"
};
};
r.setFormat(r.formatType.noneFormat);
return r;
},
"NETWORKDAYS.INTL": function () {
var r = new cBaseFunction("NETWORKDAYS.INTL");
return r;
},
"NOW": function () {
var r = new cBaseFunction("NOW");
r.setArgumentsMin(0);
r.setArgumentsMax(0);
r.Calculate = function () {
var d = new Date();
this.value = new cNumber(Math.floor((d.getTime() / 1000 - d.getTimezoneOffset() * 60) / c_sPerDay + (c_DateCorrectConst + 1)) + ((d.getHours() * 60 * 60 + d.getMinutes() * 60 + d.getSeconds()) / c_sPerDay));
this.value.numFormat = 22;
return this.setCA(this.value, true);
};
r.getInfo = function () {
return {
name: this.name,
args: "()"
};
};
return r;
},
"SECOND": function () {
var r = new cBaseFunction("SECOND");
r.setArgumentsMin(1);
r.setArgumentsMax(1);
r.Calculate = function (arg) {
var arg0 = arg[0],
val;
if (arg0 instanceof cArray) {
arg0 = arg0.getElement(0);
} else {
if (arg0 instanceof cArea || arg0 instanceof cArea3D) {
arg0 = arg0.cross(arguments[1].first).tocNumber();
}
}
if (arg0 instanceof cError) {
return this.setCA(arg0, true);
} else {
if (arg0 instanceof cNumber || arg0 instanceof cBool) {
val = arg0.tocNumber().getValue();
} else {
if (arg0 instanceof cRef || arg0 instanceof cRef3D) {
val = arg0.getValue();
if (val instanceof cError) {
return this.setCA(val, true);
} else {
if (val instanceof cNumber || val instanceof cBool) {
val = arg0.tocNumber().getValue();
} else {
return this.setCA(new cError(cErrorType.wrong_value_type), true);
}
}
} else {
if (arg0 instanceof cString) {
val = arg0.tocNumber();
if (val instanceof cError || val instanceof cEmpty) {
var d = new Date(arg0.getValue());
if (isNaN(d)) {
d = g_oFormatParser.parseDate(arg0.getValue());
if (d == null) {
return this.setCA(new cError(cErrorType.wrong_value_type), true);
}
val = d.value;
} else {
val = (d.getTime() / 1000 - d.getTimezoneOffset() * 60) / c_sPerDay + (c_DateCorrectConst + (g_bDate1904 ? 0 : 1));
}
} else {
val = arg0.tocNumber().getValue();
}
}
}
}
}
if (val < 0) {
return this.setCA(new cError(cErrorType.not_numeric), true);
} else {
val = parseInt(((val * 24 * 60 - Math.floor(val * 24 * 60)) * 60).toFixed(cExcelDateTimeDigits)) % 60;
return this.setCA(new cNumber(val), true, 0);
}
};
r.getInfo = function () {
return {
name: this.name,
args: "( time-value )"
};
};
r.setFormat(r.formatType.noneFormat);
return r;
},
"TIME": function () {
var r = new cBaseFunction("TIME");
r.setArgumentsMin(3);
r.setArgumentsMax(3);
r.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].first);
} else {
if (hour instanceof cArray) {
hour = hour.getElement(0);
}
}
if (minute instanceof cArea || minute instanceof cArea3D) {
minute = minute.cross(arguments[1].first);
} else {
if (minute instanceof cArray) {
minute = minute.getElement(0);
}
}
if (second instanceof cArea || second instanceof cArea3D) {
second = second.cross(arguments[1].first);
} else {
if (second instanceof cArray) {
second = second.getElement(0);
}
}
hour = hour.tocNumber();
minute = minute.tocNumber();
second = second.tocNumber();
if (hour instanceof cError) {
return this.setCA(hour, true);
}
if (minute instanceof cError) {
return this.setCA(minute, true);
}
if (second instanceof cError) {
return this.setCA(second, true);
}
hour = hour.getValue();
minute = minute.getValue();
second = second.getValue();
var v = (hour * 60 * 60 + minute * 60 + second) / c_sPerDay;
this.setCA(new cNumber(v - Math.floor(v)), true);
if (arguments[1].getNumFormatStr().toLowerCase() === "general") {
this.value.numFormat = 18;
}
return this.value;
};
r.getInfo = function () {
return {
name: this.name,
args: "( hour, minute, second )"
};
};
return r;
},
"TIMEVALUE": function () {
var r = new cBaseFunction("TIMEVALUE");
r.setArgumentsMin(1);
r.setArgumentsMax(1);
r.Calculate = function (arg) {
var arg0 = arg[0];
if (arg0 instanceof cArea || arg0 instanceof cArea3D) {
arg0 = arg0.cross(arguments[1].first);
} else {
if (arg0 instanceof cArray) {
arg0 = arg0.getElementRowCol(0, 0);
}
}
arg0 = arg0.tocString();
if (arg0 instanceof cError) {
return this.value = arg0;
}
if (arg0.tocNumber() instanceof cNumber && arg0.tocNumber().getValue() > 0) {
return this.value = new cNumber(parseInt(arg0.tocNumber().getValue()));
}
var res = g_oFormatParser.parse(arg0.getValue());
if (res && res.bDateTime) {
return this.value = new cNumber(res.value - parseInt(res.value));
} else {
return this.value = new cError(cErrorType.wrong_value_type);
}
};
r.getInfo = function () {
return {
name: this.name,
args: "( date-time-string )"
};
};
r.setFormat(r.formatType.noneFormat);
return r;
},
"TODAY": function () {
var r = new cBaseFunction("TODAY");
r.setArgumentsMin(0);
r.setArgumentsMax(0);
r.Calculate = function () {
this.setCA(new cNumber(new Date().getExcelDate()), true);
if (arguments[1].getNumFormatStr().toLowerCase() === "general") {
this.value.numFormat = 14;
}
return this.value;
};
r.getInfo = function () {
return {
name: this.name,
args: "()"
};
};
return r;
},
"WEEKDAY": function () {
var r = new cBaseFunction("WEEKDAY");
r.setArgumentsMin(1);
r.setArgumentsMax(2);
r.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].first);
} else {
if (arg0 instanceof cArray) {
arg0 = arg0.getElementRowCol(0, 0);
}
}
if (arg1 instanceof cArea || arg1 instanceof cArea3D) {
arg1 = arg1.cross(arguments[1].first);
} else {
if (arg1 instanceof cArray) {
arg1 = arg1.getElementRowCol(0, 0);
}
}
arg0 = arg0.tocNumber();
arg1 = arg1.tocNumber();
if (arg0 instanceof cError) {
return this.value = arg0;
}
if (arg1 instanceof cError) {
return this.value = arg1;
}
var weekday;
switch (arg1.getValue()) {
case 1:
case 17:
weekday = [1, 2, 3, 4, 5, 6, 7];
break;
case 2:
case 11:
weekday = [7, 1, 2, 3, 4, 5, 6];
break;
case 3:
weekday = [6, 0, 1, 2, 3, 4, 5];
break;
case 12:
weekday = [6, 7, 1, 2, 3, 4, 5];
break;
case 13:
weekday = [5, 6, 7, 1, 2, 3, 4];
break;
case 14:
weekday = [4, 5, 6, 7, 1, 2, 3];
break;
case 15:
weekday = [3, 4, 5, 6, 7, 1, 2];
break;
case 16:
weekday = [2, 3, 4, 5, 6, 7, 1];
break;
default:
return this.value = new cError(cErrorType.not_numeric);
}
if (arg0.getValue() < 0) {
return this.value = new cError(cErrorType.wrong_value_type);
}
return this.value = new cNumber(weekday[new Date((arg0.getValue() - (c_DateCorrectConst + 1)) * c_msPerDay).getDay()]);
};
r.getInfo = function () {
return {
name: this.name,
args: "( serial-value [ , weekday-start-flag ] )"
};
};
r.setFormat(r.formatType.noneFormat);
return r;
},
"WEEKNUM": function () {
var r = new cBaseFunction("WEEKNUM");
r.setArgumentsMin(1);
r.setArgumentsMax(2);
r.Calculate = function (arg) {
var arg0 = arg[0],
arg1 = arg[1] ? arg[1] : new cNumber(1),
type = 0;
function WeekNumber(dt, iso, type) {
dt.setHours(0, 0, 0);
var startOfYear = new Date(dt.getFullYear(), 0, 1);
var endOfYear = new Date(dt);
endOfYear.setMonth(11);
endOfYear.setDate(31);
var wk = parseInt(((dt - startOfYear) / c_msPerDay + iso[startOfYear.getDay()]) / 7);
if (type) {
switch (wk) {
case 0:
startOfYear.setDate(0);
return WeekNumber(startOfYear, iso, type);
case 53:
if (endOfYear.getDay() < 4) {
return new cNumber(1);
} else {
return new cNumber(wk);
}
default:
return new cNumber(wk);
}
} else {
wk = parseInt(((dt - startOfYear) / c_msPerDay + iso[startOfYear.getDay()] + 7) / 7);
return new cNumber(wk);
}
}
if (arg0 instanceof cArea || arg0 instanceof cArea3D) {
arg0 = arg0.cross(arguments[1].first);
} else {
if (arg0 instanceof cArray) {
arg0 = arg0.getElementRowCol(0, 0);
}
}
if (arg1 instanceof cArea || arg1 instanceof cArea3D) {
arg1 = arg1.cross(arguments[1].first);
} else {
if (arg1 instanceof cArray) {
arg1 = arg1.getElementRowCol(0, 0);
}
}
arg0 = arg0.tocNumber();
arg1 = arg1.tocNumber();
if (arg0 instanceof cError) {
return this.value = arg0;
}
if (arg1 instanceof cError) {
return this.value = arg1;
}
if (arg0.getValue() < 0) {
return this.value = new cError(cErrorType.not_numeric);
}
var weekdayStartDay;
switch (arg1.getValue()) {
case 1:
case 17:
weekdayStartDay = [0, 1, 2, 3, 4, 5, 6];
break;
case 2:
case 11:
weekdayStartDay = [6, 0, 1, 2, 3, 4, 5];
break;
case 12:
weekdayStartDay = [5, 6, 0, 1, 2, 3, 4];
break;
case 13:
weekdayStartDay = [4, 5, 6, 0, 1, 2, 3];
break;
case 14:
weekdayStartDay = [3, 4, 5, 6, 0, 1, 2];
break;
case 15:
weekdayStartDay = [2, 3, 4, 5, 6, 0, 1];
break;
case 16:
weekdayStartDay = [1, 2, 3, 4, 5, 6, 0];
break;
case 21:
weekdayStartDay = [6, 7, 8, 9, 10, 4, 5];
type = 1;
break;
default:
return this.value = new cError(cErrorType.not_numeric);
}
return this.value = new cNumber(WeekNumber(new Date((arg0.getValue() - (c_DateCorrectConst + 1)) * c_msPerDay), weekdayStartDay, type));
};
r.getInfo = function () {
return {
name: this.name,
args: "( serial-value [ , weekday-start-flag ] )"
};
};
r.setFormat(r.formatType.noneFormat);
return r;
},
"WORKDAY": function () {
var r = new cBaseFunction("WORKDAY");
r.setArgumentsMin(2);
r.setArgumentsMax(3);
r.Calculate = function (arg) {
var arg0 = arg[0],
arg1 = arg[1],
arg2 = arg[2],
arrDateIncl = [];
if (arg0 instanceof cArea || arg0 instanceof cArea3D) {
arg0 = arg0.cross(arguments[1].first);
} else {
if (arg0 instanceof cArray) {
arg0 = arg0.getElementRowCol(0, 0);
}
}
if (arg1 instanceof cArea || arg1 instanceof cArea3D) {
arg1 = arg1.cross(arguments[1].first);
} else {
if (arg1 instanceof cArray) {
arg1 = arg1.getElementRowCol(0, 0);
}
}
arg0 = arg0.tocNumber();
arg1 = arg1.tocNumber();
if (arg0 instanceof cError) {
return this.value = arg0;
}
if (arg1 instanceof cError) {
return this.value = arg1;
}
var val0 = arg0.getValue(),
val1 = arg1.getValue(),
holidays = [];
if (val0 < 0) {
return this.setCA(new cError(cErrorType.not_numeric), true);
} else {
if (!g_bDate1904) {
if (val0 < 60) {
val0 = new Date((val0 - c_DateCorrectConst) * c_msPerDay);
} else {
if (val0 == 60) {
val0 = new Date((val0 - c_DateCorrectConst - 1) * c_msPerDay);
} else {
val0 = new Date((val0 - c_DateCorrectConst - 1) * c_msPerDay);
}
}
} else {
val0 = new Date((val0 - c_DateCorrectConst) * c_msPerDay);
}
}
if (arg2) {
if (arg2 instanceof cArea || arg2 instanceof cArea3D) {
var arr = arg2.getValue();
for (var i = 0; i < arr.length; i++) {
if (arr[i] instanceof cNumber && arr[i].getValue() >= 0) {
holidays.push(arr[i]);
}
}
} else {
if (arg2 instanceof cArray) {
arg2.foreach(function (elem, r, c) {
if (elem instanceof cNumber) {
holidays.push(elem);
} else {
if (elem instanceof cString) {
var res = g_oFormatParser.parse(elem.getValue());
if (res && res.bDateTime && res.value >= 0) {
holidays.push(new cNumber(parseInt(res.value)));
}
}
}
});
}
}
}
for (var i = 0; i < holidays.length; i++) {
if (!g_bDate1904) {
if (holidays[i].getValue() < 60) {
holidays[i] = new Date((holidays[i].getValue() - c_DateCorrectConst) * c_msPerDay);
} else {
if (holidays[i] == 60) {
holidays[i] = new Date((holidays[i].getValue() - c_DateCorrectConst - 1) * c_msPerDay);
} else {
holidays[i] = new Date((holidays[i].getValue() - c_DateCorrectConst - 1) * c_msPerDay);
}
}
} else {
holidays[i] = new Date((holidays[i].getValue() - c_DateCorrectConst) * c_msPerDay);
}
}
function notAHolidays(date) {
for (var i = 0; i < holidays.length; i++) {
if (date.getTime() == holidays[i].getTime()) {
return false;
}
}
return true;
}
var dif = arg1.getValue(),
count = 1,
dif1 = dif > 0 ? 1 : dif < 0 ? -1 : 0,
val,
date = val0;
while (Math.abs(dif) > count) {
date = new Date(val0.getTime() + dif1 * c_msPerDay);
if (date.getDay() != 6 && date.getDay() != 0 && notAHolidays(date)) {
count++;
}
dif >= 0 ? dif1++:dif1--;
}
date = new Date(val0.getTime() + dif1 * c_msPerDay);
val = parseInt((date.getTime() / 1000 - date.getTimezoneOffset() * 60) / c_sPerDay + (c_DateCorrectConst + (g_bDate1904 ? 0 : 1)));
if (val < 0) {
return this.setCA(new cError(cErrorType.not_numeric), true);
}
if (arguments[1].getNumFormatStr().toLowerCase() === "general") {
return this.setCA(new cNumber(val), true, 14);
} else {
return this.setCA(new cNumber(val), true);
}
};
r.getInfo = function () {
return {
name: this.name,
args: "( start-date , day-offset [ , holidays ] )"
};
};
r.setFormat(r.formatType.noneFormat);
return r;
},
"WORKDAY.INTL": function () {
var r = new cBaseFunction("WORKDAY.INTL");
return r;
},
"YEAR": function () {
var r = new cBaseFunction("YEAR");
r.setArgumentsMin(1);
r.setArgumentsMax(1);
r.Calculate = function (arg) {
var arg0 = arg[0],
val;
if (arg0 instanceof cArray) {
arg0 = arg0.getElement(0);
} else {
if (arg0 instanceof cArea || arg0 instanceof cArea3D) {
arg0 = arg0.cross(arguments[1].first).tocNumber();
}
}
if (arg0 instanceof cError) {
return this.setCA(arg0, true);
} else {
if (arg0 instanceof cNumber || arg0 instanceof cBool) {
val = arg0.tocNumber().getValue();
} else {
if (arg0 instanceof cArea || arg0 instanceof cArea3D) {
return this.setCA(new cError(cErrorType.wrong_value_type), true);
} else {
if (arg0 instanceof cRef || arg0 instanceof cRef3D) {
val = arg0.getValue();
if (val instanceof cError) {
return this.setCA(val, true);
} else {
if (val instanceof cNumber || val instanceof cBool) {
val = arg0.tocNumber().getValue();
} else {
return this.setCA(new cError(cErrorType.wrong_value_type), true);
}
}
} else {
if (arg0 instanceof cString) {
val = arg0.tocNumber();
if (val instanceof cError || val instanceof cEmpty) {
var d = new Date(arg0.getValue());
if (isNaN(d)) {
return this.setCA(new cError(cErrorType.wrong_value_type), true);
} else {
val = Math.floor((d.getTime() / 1000 - d.getTimezoneOffset() * 60) / c_sPerDay + (c_DateCorrectConst + (g_bDate1904 ? 0 : 1)));
}
} else {
val = arg0.tocNumber().getValue();
}
}
}
}
}
}
if (val < 0) {
return this.setCA(new cError(cErrorType.not_numeric), true, 0);
} else {
return this.setCA(new cNumber((new Date((val - (c_DateCorrectConst + 1)) * c_msPerDay)).getUTCFullYear()), true, 0);
}
};
r.getInfo = function () {
return {
name: this.name,
args: "( date-value )"
};
};
r.setFormat(r.formatType.noneFormat);
return r;
},
"YEARFRAC": function () {
var r = new cBaseFunction("YEARFRAC");
r.setArgumentsMin(2);
r.setArgumentsMax(3);
r.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].first);
} else {
if (arg0 instanceof cArray) {
arg0 = arg0.getElementRowCol(0, 0);
}
}
if (arg1 instanceof cArea || arg1 instanceof cArea3D) {
arg1 = arg1.cross(arguments[1].first);
} else {
if (arg1 instanceof cArray) {
arg1 = arg1.getElementRowCol(0, 0);
}
}
if (arg2 instanceof cArea || arg2 instanceof cArea3D) {
arg2 = arg2.cross(arguments[1].first);
} else {
if (arg2 instanceof cArray) {
arg2 = arg2.getElementRowCol(0, 0);
}
}
arg0 = arg0.tocNumber();
arg1 = arg1.tocNumber();
arg2 = arg2.tocNumber();
if (arg0 instanceof cError) {
return this.value = arg0;
}
if (arg1 instanceof cError) {
return this.value = arg1;
}
if (arg2 instanceof cError) {
return this.value = arg2;
}
var val0 = arg0.getValue(),
val1 = arg1.getValue();
if (val0 < 0 || val1 < 0) {
return this.setCA(new cError(cErrorType.not_numeric), true);
}
val0 = Date.prototype.getDateFromExcel(val0);
val1 = Date.prototype.getDateFromExcel(val1);
var date1 = val0.getDate(),
date2 = val1.getDate(),
month1 = val0.getMonth(),
month2 = val1.getMonth(),
year1 = val0.getFullYear(),
year2 = val1.getFullYear();
switch (arg2.getValue()) {
case 0:
return this.value = new cNumber(Math.abs(GetDiffDate360(date1, month1, year1, val1.isLeapYear(), date2, month2, year2, false)) / 360);
break;
case 1:
var yc = Math.abs(year2 - year1),
sd = year1 > year2 ? val1 : val0,
yearAverage = sd.isLeapYear() ? 366 : 365,
dayDiff = Math.abs(val1 - val0);
for (var i = 0; i < yc; i++) {
sd.addYears(1);
yearAverage += sd.isLeapYear() ? 366 : 365;
}
yearAverage /= (yc + 1);
dayDiff /= (yearAverage * c_msPerDay);
return this.value = new cNumber(dayDiff);
break;
case 2:
var dayDiff = Math.abs(val1 - val0);
dayDiff /= (360 * c_msPerDay);
return this.value = new cNumber(dayDiff);
break;
case 3:
var dayDiff = Math.abs(val1 - val0);
dayDiff /= (365 * c_msPerDay);
return this.value = new cNumber(dayDiff);
break;
case 4:
return this.value = new cNumber(Math.abs(GetDiffDate360(date1, month1, year1, val1.isLeapYear(), date2, month2, year2, true)) / 360);
break;
default:
return this.value = new cError(cErrorType.not_numeric);
}
};
r.getInfo = function () {
return {
name: this.name,
args: "( start-date , end-date [ , basis ] )"
};
};
r.setFormat(r.formatType.noneFormat);
return r;
}
};