summaryrefslogtreecommitdiff
path: root/calc.go
diff options
context:
space:
mode:
authorxuri <xuri.me@gmail.com>2022-06-17 00:03:31 +0800
committerxuri <xuri.me@gmail.com>2022-06-17 00:03:31 +0800
commit5f4131aece5071cd98ac080b6ace85726d922f19 (patch)
treece8f7e8eb4f8e59633bb3add04ec47e08bee0859 /calc.go
parentb69da7606395bb2b05c53512663a13cce80f87d7 (diff)
ref #65, new formula function: DAYS360
Diffstat (limited to 'calc.go')
-rw-r--r--calc.go52
1 files changed, 52 insertions, 0 deletions
diff --git a/calc.go b/calc.go
index 6da0f6a..086c288 100644
--- a/calc.go
+++ b/calc.go
@@ -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:
//