diff --git a/calc.go b/calc.go index 3e402e6..266491f 100644 --- a/calc.go +++ b/calc.go @@ -323,6 +323,7 @@ type formulaFuncs struct { // DATEDIF // DATEVALUE // DAY +// DAYS // DB // DDB // DEC2BIN @@ -6574,6 +6575,58 @@ func (fn *formulaFuncs) DAY(argsList *list.List) formulaArg { return newNumberFormulaArg(float64(timeFromExcelTime(num.Number, false).Day())) } +// DAYS function returns the number of days between two supplied dates. The +// syntax of the function is: +// +// DAYS(end_date,start_date) +// +func (fn *formulaFuncs) DAYS(argsList *list.List) formulaArg { + if argsList.Len() != 2 { + return newErrorFormulaArg(formulaErrorVALUE, "DAYS requires 2 arguments") + } + var end, start float64 + endArg, startArg := argsList.Front().Value.(formulaArg), argsList.Back().Value.(formulaArg) + switch endArg.Type { + case ArgNumber: + end = endArg.Number + case ArgString: + endNum := endArg.ToNumber() + if endNum.Type == ArgNumber { + end = endNum.Number + } else { + args := list.New() + args.PushBack(endArg) + endValue := fn.DATEVALUE(args) + if endValue.Type == ArgError { + return newErrorFormulaArg(formulaErrorVALUE, formulaErrorVALUE) + } + end = endValue.Number + } + default: + return newErrorFormulaArg(formulaErrorVALUE, formulaErrorVALUE) + } + switch startArg.Type { + case ArgNumber: + start = startArg.Number + case ArgString: + startNum := startArg.ToNumber() + if startNum.Type == ArgNumber { + start = startNum.Number + } else { + args := list.New() + args.PushBack(startArg) + startValue := fn.DATEVALUE(args) + if startValue.Type == ArgError { + return newErrorFormulaArg(formulaErrorVALUE, formulaErrorVALUE) + } + start = startValue.Number + } + default: + return newErrorFormulaArg(formulaErrorVALUE, formulaErrorVALUE) + } + return newNumberFormulaArg(end - start) +} + // MONTH function returns the month of a date represented by a serial number. // The month is given as an integer, ranging from 1 (January) to 12 // (December). The syntax of the function is: diff --git a/calc_test.go b/calc_test.go index 1e4d99b..54629a6 100644 --- a/calc_test.go +++ b/calc_test.go @@ -979,6 +979,10 @@ func TestCalcCellValue(t *testing.T) { "=DAY(\"3-February-2008\")": "3", "=DAY(\"01/25/20\")": "25", "=DAY(\"01/25/31\")": "25", + // DAYS + "=DAYS(2,1)": "1", + "=DAYS(INT(2),INT(1))": "1", + "=DAYS(\"02/02/2015\",\"01/01/2015\")": "32", // MONTH "=MONTH(42171)": "6", "=MONTH(\"31-May-2015\")": "5", @@ -2040,6 +2044,12 @@ func TestCalcCellValue(t *testing.T) { "=DAY(\"3-January-9223372036854775808\")": "#VALUE!", "=DAY(\"9223372036854775808-January-1900\")": "#VALUE!", "=DAY(\"0-January-1900\")": "#VALUE!", + // DAYS + "=DAYS()": "DAYS requires 2 arguments", + "=DAYS(\"\",0)": "#VALUE!", + "=DAYS(0,\"\")": "#VALUE!", + "=DAYS(NA(),0)": "#VALUE!", + "=DAYS(0,NA())": "#VALUE!", // MONTH "=MONTH()": "MONTH requires exactly 1 argument", "=MONTH(0,0)": "MONTH requires exactly 1 argument",