diff options
author | xuri <xuri.me@gmail.com> | 2022-06-17 00:03:31 +0800 |
---|---|---|
committer | xuri <xuri.me@gmail.com> | 2022-06-17 00:03:31 +0800 |
commit | 5f4131aece5071cd98ac080b6ace85726d922f19 (patch) | |
tree | ce8f7e8eb4f8e59633bb3add04ec47e08bee0859 /calc.go | |
parent | b69da7606395bb2b05c53512663a13cce80f87d7 (diff) |
ref #65, new formula function: DAYS360
Diffstat (limited to 'calc.go')
-rw-r--r-- | calc.go | 52 |
1 files changed, 52 insertions, 0 deletions
@@ -419,6 +419,7 @@ type formulaFuncs struct { // DATEVALUE // DAY // DAYS +// DAYS360 // DB // DDB // DEC2BIN @@ -12330,6 +12331,57 @@ func (fn *formulaFuncs) DAYS(argsList *list.List) formulaArg { return newNumberFormulaArg(end.Number - start.Number) } +// DAYS360 function returns the number of days between 2 dates, based on a +// 360-day year (12 x 30 months). The syntax of the function is: +// +// DAYS360(start_date,end_date,[method]) +// +func (fn *formulaFuncs) DAYS360(argsList *list.List) formulaArg { + if argsList.Len() < 2 { + return newErrorFormulaArg(formulaErrorVALUE, "DAYS360 requires at least 2 arguments") + } + if argsList.Len() > 3 { + return newErrorFormulaArg(formulaErrorVALUE, "DAYS360 requires at most 3 arguments") + } + startDate := toExcelDateArg(argsList.Front().Value.(formulaArg)) + if startDate.Type != ArgNumber { + return startDate + } + endDate := toExcelDateArg(argsList.Front().Next().Value.(formulaArg)) + if endDate.Type != ArgNumber { + return endDate + } + start, end := timeFromExcelTime(startDate.Number, false), timeFromExcelTime(endDate.Number, false) + sy, sm, sd, ey, em, ed := start.Year(), int(start.Month()), start.Day(), end.Year(), int(end.Month()), end.Day() + method := newBoolFormulaArg(false) + if argsList.Len() > 2 { + if method = argsList.Back().Value.(formulaArg).ToBool(); method.Type != ArgNumber { + return method + } + } + if method.Number == 1 { + if sd == 31 { + sd-- + } + if ed == 31 { + ed-- + } + } else { + if getDaysInMonth(sy, sm) == sd { + sd = 30 + } + if ed > 30 { + if sd < 30 { + em++ + ed = 1 + } else { + ed = 30 + } + } + } + return newNumberFormulaArg(float64(360*(ey-sy) + 30*(em-sm) + (ed - sd))) +} + // ISOWEEKNUM function returns the ISO week number of a supplied date. The // syntax of the function is: // |