From 2cb0f8716c54db0c85c43b8df031491b3b544d0e Mon Sep 17 00:00:00 2001 From: "Dmitry.Shahtanov" <Dmitry.Shahtanov@OnlyOffice.com> Date: Wed, 3 Jul 2013 14:03:07 +0000 Subject: [PATCH] =?UTF-8?q?=D0=B4=D0=BE=D0=B1=D0=B0=D0=B2=D0=BB=D0=B5?= =?UTF-8?q?=D0=BD=D1=8B=20DATEDIF,=20DAYS360,=20YEARFRAC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit git-svn-id: svn://192.168.3.15/activex/AVS/Sources/TeamlabOffice/trunk/OfficeWeb@47677 954022d7-b5bf-4e40-9824-e11837661b57 --- Excel/.unit-tests/FormulaTests.html | 3 + Excel/.unit-tests/FormulaTests.js | 99 +++++++++- Excel/model/dateandtimeFunctions.js | 281 +++++++++++++++++++++++++--- Excel/model/parserFormula.js | 28 +++ 4 files changed, 380 insertions(+), 31 deletions(-) diff --git a/Excel/.unit-tests/FormulaTests.html b/Excel/.unit-tests/FormulaTests.html index 218e84847..129661bca 100644 --- a/Excel/.unit-tests/FormulaTests.html +++ b/Excel/.unit-tests/FormulaTests.html @@ -74,6 +74,9 @@ <script type="text/javascript" src="../apiDefines.js"></script> <script type="text/javascript" src="../api.js"></script> + <!--for presentation--> + <script type="text/javascript" src="../Common/PresentationSerializeAdapter.js"></script> + <!--for theme--> <script type="text/javascript" src="../../Common/Shapes/EditorSettings.js"></script> <script type="text/javascript" src="../../Common/Shapes/Serialize.js"></script> diff --git a/Excel/.unit-tests/FormulaTests.js b/Excel/.unit-tests/FormulaTests.js index 03c89ce21..920e11c15 100644 --- a/Excel/.unit-tests/FormulaTests.js +++ b/Excel/.unit-tests/FormulaTests.js @@ -950,6 +950,26 @@ ok( Math.abs(oParser.calculate().getValue() - 0.9180555555555560) < dif ); }) + test("Test: \"DAYS360\"",function(){ + + oParser = new parserFormula("DAYS360(DATE(2002,2,3),DATE(2005,5,31))","A2",ws); + ok(oParser.parse()); + strictEqual(oParser.calculate().getValue(), 1198); + + oParser = new parserFormula("DAYS360(DATE(2005,5,31),DATE(2002,2,3))","A2",ws); + ok(oParser.parse()); + strictEqual(oParser.calculate().getValue(), -1197); + + oParser = new parserFormula("DAYS360(DATE(2002,2,3),DATE(2005,5,31),FALSE)","A2",ws); + ok(oParser.parse()); + strictEqual(oParser.calculate().getValue(), 1198); + + oParser = new parserFormula("DAYS360(DATE(2002,2,3),DATE(2005,5,31),TRUE)","A2",ws); + ok(oParser.parse()); + strictEqual(oParser.calculate().getValue(), 1197); + + }) + test("Test: \"WEEKNUM\"",function(){ oParser = new parserFormula("WEEKNUM(DATE(2006,1,1))","A2",ws); ok(oParser.parse()); @@ -1007,36 +1027,101 @@ ok(oParser.parse()); strictEqual( oParser.calculate().getValue(), 1); - oParser = new parserFormula("WEEKNUM(DATE(2008,1,4),11)","A2",ws);//вÑк + oParser = new parserFormula("WEEKNUM(DATE(2008,1,4),11)","A2",ws); ok(oParser.parse()); strictEqual( oParser.calculate().getValue(), 1); - oParser = new parserFormula("WEEKNUM(DATE(2008,1,10),11)","A2",ws);//вÑк + oParser = new parserFormula("WEEKNUM(DATE(2008,1,10),11)","A2",ws); ok(oParser.parse()); strictEqual( oParser.calculate().getValue(), 2); - oParser = new parserFormula("WEEKNUM(DATE(2008,1,11),11)","A2",ws);//вÑк + oParser = new parserFormula("WEEKNUM(DATE(2008,1,11),11)","A2",ws); ok(oParser.parse()); strictEqual( oParser.calculate().getValue(), 2); - oParser = new parserFormula("WEEKNUM(DATE(2008,1,17),11)","A2",ws);//вÑк + oParser = new parserFormula("WEEKNUM(DATE(2008,1,17),11)","A2",ws); ok(oParser.parse()); strictEqual( oParser.calculate().getValue(), 3); - oParser = new parserFormula("WEEKNUM(DATE(2008,1,18),11)","A2",ws);//вÑк + oParser = new parserFormula("WEEKNUM(DATE(2008,1,18),11)","A2",ws); ok(oParser.parse()); strictEqual( oParser.calculate().getValue(), 3); - oParser = new parserFormula("WEEKNUM(DATE(2008,1,24),11)","A2",ws);//вÑк + oParser = new parserFormula("WEEKNUM(DATE(2008,1,24),11)","A2",ws); ok(oParser.parse()); strictEqual( oParser.calculate().getValue(), 4); - oParser = new parserFormula("WEEKNUM(DATE(2013,1,1),21)","A2",ws);//вÑк + oParser = new parserFormula("WEEKNUM(DATE(2013,1,1),21)","A2",ws); ok(oParser.parse()); strictEqual( oParser.calculate().getValue(), 1); + oParser = new parserFormula("WEEKNUM(DATE(2013,1,7))","A2",ws); + ok(oParser.parse()); + strictEqual( oParser.calculate().getValue(), 2); + + }) + + test("Test: \"YEARFRAC\"",function(){ + function okWrapper(a,b){ + ok( Math.abs(a - b) < dif ); + } + oParser = new parserFormula("YEARFRAC(DATE(2006,1,1),DATE(2006,3,26))","A2",ws); + ok(oParser.parse()); + okWrapper( oParser.calculate().getValue(), 0.236111111); + + oParser = new parserFormula("YEARFRAC(DATE(2006,3,26),DATE(2006,1,1))","A2",ws); + ok(oParser.parse()); + okWrapper( oParser.calculate().getValue(), 0.236111111); + + oParser = new parserFormula("YEARFRAC(DATE(2006,1,1),DATE(2006,7,1))","A2",ws); + ok(oParser.parse()); + okWrapper( oParser.calculate().getValue(), 0.5); + + oParser = new parserFormula("YEARFRAC(DATE(2006,1,1),DATE(2007,9,1))","A2",ws); + ok(oParser.parse()); + okWrapper( oParser.calculate().getValue(), 1.666666667); + + oParser = new parserFormula("YEARFRAC(DATE(2006,1,1),DATE(2006,7,1),0)","A2",ws); + ok(oParser.parse()); + okWrapper( oParser.calculate().getValue(), 0.5); + + oParser = new parserFormula("YEARFRAC(DATE(2006,1,1),DATE(2006,7,1),1)","A2",ws); + ok(oParser.parse()); + okWrapper( oParser.calculate().getValue(), 0.495890411); + + oParser = new parserFormula("YEARFRAC(DATE(2006,1,1),DATE(2006,7,1),2)","A2",ws); + ok(oParser.parse()); + okWrapper( oParser.calculate().getValue(), 0.502777778); + + oParser = new parserFormula("YEARFRAC(DATE(2006,1,1),DATE(2006,7,1),3)","A2",ws); + ok(oParser.parse()); + okWrapper( oParser.calculate().getValue(), 0.495890411); + + oParser = new parserFormula("YEARFRAC(DATE(2006,1,1),DATE(2006,7,1),4)","A2",ws); + ok(oParser.parse()); + okWrapper( oParser.calculate().getValue(), 0.5); + + oParser = new parserFormula("YEARFRAC(DATE(2004,3,1),DATE(2006,3,1),1)","A2",ws); + ok(oParser.parse()); + okWrapper( oParser.calculate().getValue(), 1.998175182481752); }) + test("Test: \"DATEDIF\"",function(){ + oParser = new parserFormula("DATEDIF(DATE(2001,1,1),DATE(2003,1,1),\"Y\")","A2",ws); + ok(oParser.parse()); + strictEqual( oParser.calculate().getValue(), 2); + oParser = new parserFormula("DATEDIF(DATE(2001,6,1),DATE(2002,8,15),\"D\")","A2",ws); + ok(oParser.parse()); + strictEqual( oParser.calculate().getValue(), 440); + + oParser = new parserFormula("DATEDIF(DATE(2001,6,1),DATE(2002,8,15),\"YD\")","A2",ws); + ok(oParser.parse()); + strictEqual( oParser.calculate().getValue(), 75); + + oParser = new parserFormula("DATEDIF(DATE(2001,6,1),DATE(2002,8,15),\"MD\")","A2",ws); + ok(oParser.parse()); + strictEqual( oParser.calculate().getValue(), 14); + }) }); diff --git a/Excel/model/dateandtimeFunctions.js b/Excel/model/dateandtimeFunctions.js index aab7d8350..9497aaa57 100644 --- a/Excel/model/dateandtimeFunctions.js +++ b/Excel/model/dateandtimeFunctions.js @@ -5,9 +5,31 @@ * Time: 13:24 * To change this template use File | Settings | File Templates. */ +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(){ + 'DATE' : function(){ var r = new cBaseFunction("DATE"); r.setArgumentsMin(3); r.setArgumentsMax(3); @@ -61,7 +83,7 @@ cFormulaFunction.DateAndTime = { if( month == 0 ){ return this.setCA(new cError( cErrorType.not_numeric ),true); } - this.value = new cNumber( Math.round( ( ( new Date(year, month - 1, day) ).getTime()/1000 )/c_sPerDay+(c_DateCorrectConst+1) ) ) + this.value = new cNumber( Math.round( new Date(year, month - 1, day ).getExcelDate() ) ) this.value.numFormat = 14; this.value.ca = true; return this.value; @@ -76,6 +98,103 @@ cFormulaFunction.DateAndTime = { }, '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(){ @@ -158,8 +277,7 @@ cFormulaFunction.DateAndTime = { } if(val < 0) return this.setCA(new cError( cErrorType.not_numeric ),true); - else if(!g_bDate1904) - { + 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 ) @@ -181,6 +299,56 @@ cFormulaFunction.DateAndTime = { }, '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(){ @@ -472,7 +640,6 @@ cFormulaFunction.DateAndTime = { } if(val < 0) return this.setCA( new cError( cErrorType.not_numeric ) ,true); - else if(!g_bDate1904){ if( val == 60 ) return this.setCA( new cNumber( 2 ) ,true,0); @@ -572,16 +739,7 @@ cFormulaFunction.DateAndTime = { } 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); + holidays[i] = Date.prototype.getDateFromExcel( holidays[i].getValue() ); } function includeInHolidays(date){ @@ -599,8 +757,6 @@ cFormulaFunction.DateAndTime = { if( date.getDay() != 5 && date.getDay() != 6 && includeInHolidays(date) ) count++; } - - return this.value = new cNumber( (dif<0?-1:1)*count ); } r.getInfo = function(){ @@ -699,7 +855,6 @@ cFormulaFunction.DateAndTime = { var r = new cBaseFunction("TIME"); r.setArgumentsMin(3); r.setArgumentsMax(3); - //to excel (hh*60*60+mm*60+ss)/c_sPerDay (c_sPerDay the number of seconds in a day) r.Calculate = function(arg){ var hour,minute,second; for (var i = 0; i<this.argumentsCurrent;i++){ @@ -796,9 +951,7 @@ cFormulaFunction.DateAndTime = { r.setArgumentsMin(0); r.setArgumentsMax(0); r.Calculate = function(){ - var d = new Date(); - // 1 2 3 3 4 5 5 4 2 1 - this.setCA( new cNumber( Math.floor( ( d.getTime()/1000 - d.getTimezoneOffset()*60 )/c_sPerDay+( c_DateCorrectConst + (g_bDate1904?0:1) ) ) ) ,true); + this.setCA( new cNumber( new Date().getExcelDate() ), true); if( arguments[1].getNumFormatStr().toLowerCase() === "general" ) this.value.numFormat = 14; return this.value; @@ -810,7 +963,6 @@ cFormulaFunction.DateAndTime = { }; } return r; - //Math.floor(((new Date()).getTime()/1000)/c_sPerDay+(c_DateCorrectConst+1)) from UTC-timestamp to excel 2010 }, 'WEEKDAY' : function(){ var r = new cBaseFunction("WEEKDAY"); @@ -890,7 +1042,6 @@ cFormulaFunction.DateAndTime = { }, 'WEEKNUM' : function(){ var r = new cBaseFunction("WEEKNUM"); - //var d = new Date(), iso = [6,7,8,9,10,4,5]; console.log(d); var b = new Date(d.getFullYear(), 0, 1); var c = ((d-b)/(86400000)+iso[b.getDay()])/7; console.log(c) r.setArgumentsMin(1); r.setArgumentsMax(2); r.Calculate = function(arg){ @@ -1106,7 +1257,7 @@ cFormulaFunction.DateAndTime = { args:"( start-date , day-offset [ , holidays ] )" }; } - // r.setFormat(r.formatType.noneFormat); + r.setFormat(r.formatType.noneFormat); return r; }, 'WORKDAY.INTL' : function(){ @@ -1173,6 +1324,88 @@ cFormulaFunction.DateAndTime = { }, '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; } } \ No newline at end of file diff --git a/Excel/model/parserFormula.js b/Excel/model/parserFormula.js index 0ad6ae22a..d4f523efc 100644 --- a/Excel/model/parserFormula.js +++ b/Excel/model/parserFormula.js @@ -57,6 +57,34 @@ Date.prototype.getDaysInMonth.R = [31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 3 // durations of months for the leap year Date.prototype.getDaysInMonth.L = [31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31]; +Date.prototype.getExcelDate = function(){ + return Math.floor( ( this.getTime()/1000 - this.getTimezoneOffset()*60 )/c_sPerDay+( c_DateCorrectConst + (g_bDate1904?0:1) ) ) +} + +Date.prototype.getDateFromExcel = function(val){ + if(!g_bDate1904){ + if( val < 60 ) + return new Date((val-c_DateCorrectConst)*c_msPerDay); + else if( val == 60 ) + return new Date((val-c_DateCorrectConst-1)*c_msPerDay); + else + return new Date((val-c_DateCorrectConst-1)*c_msPerDay); + } + else + return new Date((val-c_DateCorrectConst)*c_msPerDay); +} + +Date.prototype.addYears = function(counts){ + this.setYear(this.getFullYear()+counts); +} + +Date.prototype.addMonths = function(counts){ + this.setMonth(this.getMonth()+counts); +} + +Date.prototype.addDays = function(counts){ + this.setDate(this.getDate()+counts); +} var _func = [];//Ð´Ð»Ñ Ð²ÐµÐ»Ð¾Ñипеда а-Ð»Ñ Ð¿ÐµÑ€ÐµÐ³Ñ€ÑƒÐ·ÐºÐ° функций. _func[cElementType.number] = []; -- 2.30.9