From 2add938798cdd1456616869298319528b0c76913 Mon Sep 17 00:00:00 2001 From: xuri Date: Fri, 17 Sep 2021 00:15:51 +0800 Subject: - new formula functions: DATEVALUE, ref #65 - fix ineffectual variable assignments - timeout in go test --- .github/workflows/go.yml | 2 +- calc.go | 25 +++++++++++++++++++++++++ calc_test.go | 9 +++++++++ cell.go | 2 +- 4 files changed, 36 insertions(+), 2 deletions(-) diff --git a/.github/workflows/go.yml b/.github/workflows/go.yml index 320e3da..5f674c3 100644 --- a/.github/workflows/go.yml +++ b/.github/workflows/go.yml @@ -28,7 +28,7 @@ jobs: run: go build -v . - name: Test - run: env GO111MODULE=on go test -v -race ./... -coverprofile=coverage.txt -covermode=atomic + run: env GO111MODULE=on go test -v -timeout 30m -race ./... -coverprofile=coverage.txt -covermode=atomic - name: Codecov uses: codecov/codecov-action@v1 diff --git a/calc.go b/calc.go index 9cbc8ec..3e402e6 100644 --- a/calc.go +++ b/calc.go @@ -321,6 +321,7 @@ type formulaFuncs struct { // CUMPRINC // DATE // DATEDIF +// DATEVALUE // DAY // DB // DDB @@ -6515,6 +6516,30 @@ func strToDate(str string) (int, int, int, bool, formulaArg) { return year, month, day, timeIsEmpty, newEmptyFormulaArg() } +// DATEVALUE function converts a text representation of a date into an Excel +// date. For example, the function converts a text string representing a +// date, into the serial number that represents the date in Excel's date-time +// code. The syntax of the function is: +// +// DATEVALUE(date_text) +// +func (fn *formulaFuncs) DATEVALUE(argsList *list.List) formulaArg { + if argsList.Len() != 1 { + return newErrorFormulaArg(formulaErrorVALUE, "DATEVALUE requires 1 argument") + } + dateText := argsList.Front().Value.(formulaArg).Value() + if !isDateOnlyFmt(dateText) { + if _, _, _, _, _, err := strToTime(dateText); err.Type == ArgError { + return err + } + } + y, m, d, _, err := strToDate(dateText) + if err.Type == ArgError { + return err + } + return newNumberFormulaArg(daysBetween(excelMinTime1900.Unix(), makeDate(y, time.Month(m), d)) + 1) +} + // DAY function returns the day of a date, represented by a serial number. The // day is given as an integer ranging from 1 to 31. The syntax of the // function is: diff --git a/calc_test.go b/calc_test.go index 763ea1f..1e4d99b 100644 --- a/calc_test.go +++ b/calc_test.go @@ -956,6 +956,11 @@ func TestCalcCellValue(t *testing.T) { "=DATEDIF(43101,43891,\"YD\")": "59", "=DATEDIF(36526,73110,\"YD\")": "60", "=DATEDIF(42171,44242,\"yd\")": "244", + // DATEVALUE + "=DATEVALUE(\"01/01/16\")": "42370", + "=DATEVALUE(\"01/01/2016\")": "42370", + "=DATEVALUE(\"01/01/29\")": "47119", + "=DATEVALUE(\"01/01/30\")": "10959", // DAY "=DAY(0)": "0", "=DAY(INT(7))": "7", @@ -1997,6 +2002,10 @@ func TestCalcCellValue(t *testing.T) { "=DATEDIF(\"\",\"\",\"\")": "strconv.ParseFloat: parsing \"\": invalid syntax", "=DATEDIF(43891,43101,\"Y\")": "start_date > end_date", "=DATEDIF(43101,43891,\"x\")": "DATEDIF has invalid unit", + // DATEVALUE + "=DATEVALUE()": "DATEVALUE requires 1 argument", + "=DATEVALUE(\"01/01\")": "#VALUE!", // valid in Excel, which uses years by the system date + "=DATEVALUE(\"1900-0-0\")": "#VALUE!", // DAY "=DAY()": "DAY requires exactly 1 argument", "=DAY(-1)": "DAY only accepts positive argument", diff --git a/cell.go b/cell.go index 2d49a5e..902f5b7 100644 --- a/cell.go +++ b/cell.go @@ -82,7 +82,7 @@ func (f *File) GetCellType(sheet, axis string) (CellType, error) { var ( err error cellTypeStr string - cellType CellType = CellTypeUnset + cellType CellType ) if cellTypeStr, err = f.getCellStringFunc(sheet, axis, func(x *xlsxWorksheet, c *xlsxC) (string, bool, error) { return c.T, true, nil -- cgit v1.2.1