Skip to content

Commit df22bb5

Browse files
committed
ref qax-os#65, new formula function: DAYS360
1 parent e101c71 commit df22bb5

File tree

2 files changed

+67
-0
lines changed

2 files changed

+67
-0
lines changed

calc.go

+52
Original file line numberDiff line numberDiff line change
@@ -419,6 +419,7 @@ type formulaFuncs struct {
419419
// DATEVALUE
420420
// DAY
421421
// DAYS
422+
// DAYS360
422423
// DB
423424
// DDB
424425
// DEC2BIN
@@ -12330,6 +12331,57 @@ func (fn *formulaFuncs) DAYS(argsList *list.List) formulaArg {
1233012331
return newNumberFormulaArg(end.Number - start.Number)
1233112332
}
1233212333

12334+
// DAYS360 function returns the number of days between 2 dates, based on a
12335+
// 360-day year (12 x 30 months). The syntax of the function is:
12336+
//
12337+
// DAYS360(start_date,end_date,[method])
12338+
//
12339+
func (fn *formulaFuncs) DAYS360(argsList *list.List) formulaArg {
12340+
if argsList.Len() < 2 {
12341+
return newErrorFormulaArg(formulaErrorVALUE, "DAYS360 requires at least 2 arguments")
12342+
}
12343+
if argsList.Len() > 3 {
12344+
return newErrorFormulaArg(formulaErrorVALUE, "DAYS360 requires at most 3 arguments")
12345+
}
12346+
startDate := toExcelDateArg(argsList.Front().Value.(formulaArg))
12347+
if startDate.Type != ArgNumber {
12348+
return startDate
12349+
}
12350+
endDate := toExcelDateArg(argsList.Front().Next().Value.(formulaArg))
12351+
if endDate.Type != ArgNumber {
12352+
return endDate
12353+
}
12354+
start, end := timeFromExcelTime(startDate.Number, false), timeFromExcelTime(endDate.Number, false)
12355+
sy, sm, sd, ey, em, ed := start.Year(), int(start.Month()), start.Day(), end.Year(), int(end.Month()), end.Day()
12356+
method := newBoolFormulaArg(false)
12357+
if argsList.Len() > 2 {
12358+
if method = argsList.Back().Value.(formulaArg).ToBool(); method.Type != ArgNumber {
12359+
return method
12360+
}
12361+
}
12362+
if method.Number == 1 {
12363+
if sd == 31 {
12364+
sd--
12365+
}
12366+
if ed == 31 {
12367+
ed--
12368+
}
12369+
} else {
12370+
if getDaysInMonth(sy, sm) == sd {
12371+
sd = 30
12372+
}
12373+
if ed > 30 {
12374+
if sd < 30 {
12375+
em++
12376+
ed = 1
12377+
} else {
12378+
ed = 30
12379+
}
12380+
}
12381+
}
12382+
return newNumberFormulaArg(float64(360*(ey-sy) + 30*(em-sm) + (ed - sd)))
12383+
}
12384+
1233312385
// ISOWEEKNUM function returns the ISO week number of a supplied date. The
1233412386
// syntax of the function is:
1233512387
//

calc_test.go

+15
Original file line numberDiff line numberDiff line change
@@ -1476,6 +1476,15 @@ func TestCalcCellValue(t *testing.T) {
14761476
"=DAYS(2,1)": "1",
14771477
"=DAYS(INT(2),INT(1))": "1",
14781478
"=DAYS(\"02/02/2015\",\"01/01/2015\")": "32",
1479+
// DAYS360
1480+
"=DAYS360(\"10/10/2020\", \"10/10/2020\")": "0",
1481+
"=DAYS360(\"01/30/1999\", \"02/28/1999\")": "28",
1482+
"=DAYS360(\"01/31/1999\", \"02/28/1999\")": "28",
1483+
"=DAYS360(\"12/12/1999\", \"08/31/1999\")": "-101",
1484+
"=DAYS360(\"12/12/1999\", \"11/30/1999\")": "-12",
1485+
"=DAYS360(\"12/12/1999\", \"11/30/1999\",TRUE)": "-12",
1486+
"=DAYS360(\"01/31/1999\", \"03/31/1999\",TRUE)": "60",
1487+
"=DAYS360(\"01/31/1999\", \"03/31/2000\",FALSE)": "420",
14791488
// EDATE
14801489
"=EDATE(\"01/01/2021\",-1)": "44166",
14811490
"=EDATE(\"01/31/2020\",1)": "43890",
@@ -3447,6 +3456,12 @@ func TestCalcCellValue(t *testing.T) {
34473456
"=DAYS(0,\"\")": "#VALUE!",
34483457
"=DAYS(NA(),0)": "#VALUE!",
34493458
"=DAYS(0,NA())": "#VALUE!",
3459+
// DAYS360
3460+
"=DAYS360(\"12/12/1999\")": "DAYS360 requires at least 2 arguments",
3461+
"=DAYS360(\"12/12/1999\", \"11/30/1999\",TRUE,\"\")": "DAYS360 requires at most 3 arguments",
3462+
"=DAYS360(\"12/12/1999\", \"11/30/1999\",\"\")": "strconv.ParseBool: parsing \"\": invalid syntax",
3463+
"=DAYS360(\"12/12/1999\", \"\")": "#VALUE!",
3464+
"=DAYS360(\"\", \"11/30/1999\")": "#VALUE!",
34503465
// EDATE
34513466
"=EDATE()": "EDATE requires 2 arguments",
34523467
"=EDATE(0,\"\")": "strconv.ParseFloat: parsing \"\": invalid syntax",

0 commit comments

Comments
 (0)