diff --git a/calc.go b/calc.go index 9f3e25fa428850a51e6611e0222be8e6c9548324..e59d344bfbdaf5709f36b2f7522397f7de39a5bb 100644 --- a/calc.go +++ b/calc.go @@ -504,6 +504,7 @@ type formulaFuncs struct { // VAR.P // VARP // VLOOKUP +// YEAR // func (f *File) CalcCellValue(sheet, cell string) (result string, err error) { var ( @@ -6445,6 +6446,36 @@ func (fn *formulaFuncs) MONTH(argsList *list.List) formulaArg { return newNumberFormulaArg(float64(timeFromExcelTime(num.Number, false).Month())) } +// YEAR function returns an integer representing the year of a supplied date. +// The syntax of the function is: +// +// YEAR(serial_number) +// +func (fn *formulaFuncs) YEAR(argsList *list.List) formulaArg { + if argsList.Len() != 1 { + return newErrorFormulaArg(formulaErrorVALUE, "YEAR requires exactly 1 argument") + } + arg := argsList.Front().Value.(formulaArg) + num := arg.ToNumber() + if num.Type != ArgNumber { + dateString := strings.ToLower(arg.Value()) + if !isDateOnlyFmt(dateString) { + if _, _, _, _, _, err := strToTime(dateString); err.Type == ArgError { + return err + } + } + year, _, _, _, err := strToDate(dateString) + if err.Type == ArgError { + return err + } + return newNumberFormulaArg(float64(year)) + } + if num.Number < 0 { + return newErrorFormulaArg(formulaErrorNUM, "YEAR only accepts positive argument") + } + return newNumberFormulaArg(float64(timeFromExcelTime(num.Number, false).Year())) +} + // NOW function returns the current date and time. The function receives no // arguments and therefore. The syntax of the function is: // diff --git a/calc_test.go b/calc_test.go index cea95210ddfb6a8da596edeafd5f887c8f12ac73..e5a6e1e09d0fad8f5d85c66a28302b6edfb13108 100644 --- a/calc_test.go +++ b/calc_test.go @@ -965,6 +965,13 @@ func TestCalcCellValue(t *testing.T) { // MONTH "=MONTH(42171)": "6", "=MONTH(\"31-May-2015\")": "5", + // YEAR + "=YEAR(15)": "1900", + "=YEAR(\"15\")": "1900", + "=YEAR(2048)": "1905", + "=YEAR(42171)": "2015", + "=YEAR(\"29-May-2015\")": "2015", + "=YEAR(\"05/03/1984\")": "1984", // Text Functions // CHAR "=CHAR(65)": "A", @@ -1986,10 +1993,16 @@ func TestCalcCellValue(t *testing.T) { "=DAY(\"0-January-1900\")": "#VALUE!", // MONTH "=MONTH()": "MONTH requires exactly 1 argument", - "=MONTH(43891,43101)": "MONTH requires exactly 1 argument", + "=MONTH(0,0)": "MONTH requires exactly 1 argument", "=MONTH(-1)": "MONTH only accepts positive argument", "=MONTH(\"text\")": "#VALUE!", "=MONTH(\"January 25, 100\")": "#VALUE!", + // YEAR + "=YEAR()": "YEAR requires exactly 1 argument", + "=YEAR(0,0)": "YEAR requires exactly 1 argument", + "=YEAR(-1)": "YEAR only accepts positive argument", + "=YEAR(\"text\")": "#VALUE!", + "=YEAR(\"January 25, 100\")": "#VALUE!", // NOW "=NOW(A1)": "NOW accepts no arguments", // TODAY