summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorxuri <xuri.me@gmail.com>2021-09-24 08:19:48 +0800
committerxuri <xuri.me@gmail.com>2021-09-24 08:19:48 +0800
commitc05b9fe8a6e6cadad0de7821bd33fa5cc283c8e4 (patch)
tree7da5ed9337aaf991b41994b8c537567bb6c08506
parent790c363cceaaa09e91ad579e2d25cb13c1582bba (diff)
new formula function: DAYS, ref #65
-rw-r--r--calc.go53
-rw-r--r--calc_test.go10
2 files changed, 63 insertions, 0 deletions
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",