summaryrefslogtreecommitdiff
path: root/calc.go
diff options
context:
space:
mode:
authorxuri <xuri.me@gmail.com>2021-08-15 00:06:40 +0800
committerxuri <xuri.me@gmail.com>2021-08-15 00:06:40 +0800
commit48c16de8bf74df0fa94a30d29e2e7e3446d48433 (patch)
tree329a2e4ab896982581bd348a1700d75aeb40a517 /calc.go
parentf6f14f507ee1adf4883cb1b12f27932a63afb286 (diff)
Improve security and simplify code
- Make variable name more semantic - Reduce cyclomatic complexities for the formula calculate function - Support specified unzip size limit on open file options, avoid zip bombs vulnerability attack - Typo fix for documentation and error message
Diffstat (limited to 'calc.go')
-rw-r--r--calc.go59
1 files changed, 35 insertions, 24 deletions
diff --git a/calc.go b/calc.go
index a03520b..eb6ff75 100644
--- a/calc.go
+++ b/calc.go
@@ -6026,6 +6026,39 @@ func (fn *formulaFuncs) DATE(argsList *list.List) formulaArg {
return newStringFormulaArg(timeFromExcelTime(daysBetween(excelMinTime1900.Unix(), d)+1, false).String())
}
+// calcDateDif is an implementation of the formula function DATEDIF,
+// calculation difference between two dates.
+func calcDateDif(unit string, diff float64, seq []int, startArg, endArg formulaArg) float64 {
+ ey, sy, em, sm, ed, sd := seq[0], seq[1], seq[2], seq[3], seq[4], seq[5]
+ switch unit {
+ case "d":
+ diff = endArg.Number - startArg.Number
+ case "md":
+ smMD := em
+ if ed < sd {
+ smMD--
+ }
+ diff = endArg.Number - daysBetween(excelMinTime1900.Unix(), makeDate(ey, time.Month(smMD), sd)) - 1
+ case "ym":
+ diff = float64(em - sm)
+ if ed < sd {
+ diff--
+ }
+ if diff < 0 {
+ diff += 12
+ }
+ case "yd":
+ syYD := sy
+ if em < sm || (em == sm && ed < sd) {
+ syYD++
+ }
+ s := daysBetween(excelMinTime1900.Unix(), makeDate(syYD, time.Month(em), ed))
+ e := daysBetween(excelMinTime1900.Unix(), makeDate(sy, time.Month(sm), sd))
+ diff = s - e
+ }
+ return diff
+}
+
// DATEDIF function calculates the number of days, months, or years between
// two dates. The syntax of the function is:
//
@@ -6051,8 +6084,6 @@ func (fn *formulaFuncs) DATEDIF(argsList *list.List) formulaArg {
ey, emm, ed := endDate.Date()
sm, em, diff := int(smm), int(emm), 0.0
switch unit {
- case "d":
- return newNumberFormulaArg(endArg.Number - startArg.Number)
case "y":
diff = float64(ey - sy)
if em < sm || (em == sm && ed < sd) {
@@ -6069,28 +6100,8 @@ func (fn *formulaFuncs) DATEDIF(argsList *list.List) formulaArg {
mdiff += 12
}
diff = float64(ydiff*12 + mdiff)
- case "md":
- smMD := em
- if ed < sd {
- smMD--
- }
- diff = endArg.Number - daysBetween(excelMinTime1900.Unix(), makeDate(ey, time.Month(smMD), sd)) - 1
- case "ym":
- diff = float64(em - sm)
- if ed < sd {
- diff--
- }
- if diff < 0 {
- diff += 12
- }
- case "yd":
- syYD := sy
- if em < sm || (em == sm && ed < sd) {
- syYD++
- }
- s := daysBetween(excelMinTime1900.Unix(), makeDate(syYD, time.Month(em), ed))
- e := daysBetween(excelMinTime1900.Unix(), makeDate(sy, time.Month(sm), sd))
- diff = s - e
+ case "d", "md", "ym", "yd":
+ diff = calcDateDif(unit, diff, []int{ey, sy, em, sm, ed, sd}, startArg, endArg)
default:
return newErrorFormulaArg(formulaErrorVALUE, "DATEDIF has invalid unit")
}