diff --git a/calc.go b/calc.go index 7e1fa71e..eff012fd 100644 --- a/calc.go +++ b/calc.go @@ -769,7 +769,7 @@ type formulaFuncs struct { // ZTEST func (f *File) CalcCellValue(sheet, cell string, opts ...Options) (result string, err error) { var ( - rawCellValue = parseOptions(opts...).RawCellValue + rawCellValue = getOptions(opts...).RawCellValue styleIdx int token formulaArg ) diff --git a/cell.go b/cell.go index caae7747..3005222c 100644 --- a/cell.go +++ b/cell.go @@ -71,7 +71,7 @@ func (f *File) GetCellValue(sheet, cell string, opts ...Options) (string, error) if err != nil { return "", true, err } - val, err := c.getValueFrom(f, sst, parseOptions(opts...).RawCellValue) + val, err := c.getValueFrom(f, sst, getOptions(opts...).RawCellValue) return val, true, err }) } @@ -640,12 +640,12 @@ type FormulaOpts struct { // // err := f.SetCellFormula("Sheet1", "A3", "=SUM(A1,B1)") // -// Example 2, set one-dimensional vertical constant array (row array) formula +// Example 2, set one-dimensional vertical constant array (column array) formula // "1,2,3" for the cell "A3" on "Sheet1": // -// err := f.SetCellFormula("Sheet1", "A3", "={1,2,3}") +// err := f.SetCellFormula("Sheet1", "A3", "={1;2;3}") // -// Example 3, set one-dimensional horizontal constant array (column array) +// Example 3, set one-dimensional horizontal constant array (row array) // formula '"a","b","c"' for the cell "A3" on "Sheet1": // // err := f.SetCellFormula("Sheet1", "A3", "={\"a\",\"b\",\"c\"}") @@ -654,7 +654,7 @@ type FormulaOpts struct { // the cell "A3" on "Sheet1": // // formulaType, ref := excelize.STCellFormulaTypeArray, "A3:A3" -// err := f.SetCellFormula("Sheet1", "A3", "={1,2,\"a\",\"b\"}", +// err := f.SetCellFormula("Sheet1", "A3", "={1,2;\"a\",\"b\"}", // excelize.FormulaOpts{Ref: &ref, Type: &formulaType}) // // Example 5, set range array formula "A1:A2" for the cell "A3" on "Sheet1": diff --git a/col.go b/col.go index bb1ffd5c..d3852048 100644 --- a/col.go +++ b/col.go @@ -92,7 +92,7 @@ func (cols *Cols) Rows(opts ...Options) ([]string, error) { if cols.stashCol >= cols.curCol { return rowIterator.cells, rowIterator.err } - cols.rawCellValue = parseOptions(opts...).RawCellValue + cols.rawCellValue = getOptions(opts...).RawCellValue if cols.sst, rowIterator.err = cols.f.sharedStringsReader(); rowIterator.err != nil { return rowIterator.cells, rowIterator.err } diff --git a/date.go b/date.go index b3cbb75c..94ce2183 100644 --- a/date.go +++ b/date.go @@ -156,7 +156,11 @@ func timeFromExcelTime(excelTime float64, date1904 bool) time.Time { date = excel1900Epoc } durationPart := time.Duration(nanosInADay * floatPart) - return date.AddDate(0, 0, wholeDaysPart).Add(durationPart).Truncate(time.Second) + date = date.AddDate(0, 0, wholeDaysPart).Add(durationPart) + if date.Nanosecond()/1e6 > 500 { + return date.Round(time.Second) + } + return date.Truncate(time.Second) } // ExcelDateToTime converts a float-based excel date representation to a time.Time. diff --git a/excelize.go b/excelize.go index 5a47f203..a2b61a77 100644 --- a/excelize.go +++ b/excelize.go @@ -161,7 +161,7 @@ func OpenReader(r io.Reader, opts ...Options) (*File, error) { return nil, err } f := newFile() - f.options = parseOptions(opts...) + f.options = getOptions(opts...) if err = f.checkOpenReaderOptions(); err != nil { return nil, err } @@ -198,9 +198,9 @@ func OpenReader(r io.Reader, opts ...Options) (*File, error) { return f, err } -// parseOptions provides a function to parse the optional settings for open +// getOptions provides a function to parse the optional settings for open // and reading spreadsheet. -func parseOptions(opts ...Options) *Options { +func getOptions(opts ...Options) *Options { options := &Options{} for _, opt := range opts { options = &opt diff --git a/numfmt_test.go b/numfmt_test.go index f45307d5..5540fb1d 100644 --- a/numfmt_test.go +++ b/numfmt_test.go @@ -49,9 +49,9 @@ func TestNumFmt(t *testing.T) { {"43543.086539351854", "AM/PM hh:mm:ss a/p", "AM 02:04:37 a"}, {"43528", "YYYY", "2019"}, {"43528", "", "43528"}, - {"43528.2123", "YYYY-MM-DD hh:mm:ss", "2019-03-04 05:05:42"}, - {"43528.2123", "YYYY-MM-DD hh:mm:ss;YYYY-MM-DD hh:mm:ss", "2019-03-04 05:05:42"}, - {"43528.2123", "M/D/YYYY h:m:s", "3/4/2019 5:5:42"}, + {"43528.2123", "YYYY-MM-DD hh:mm:ss", "2019-03-04 05:05:43"}, + {"43528.2123", "YYYY-MM-DD hh:mm:ss;YYYY-MM-DD hh:mm:ss", "2019-03-04 05:05:43"}, + {"43528.2123", "M/D/YYYY h:m:s", "3/4/2019 5:5:43"}, {"43528.003958333335", "m/d/yyyy h:m:s", "3/4/2019 0:5:42"}, {"43528.003958333335", "M/D/YYYY h:mm:s", "3/4/2019 0:05:42"}, {"0.64583333333333337", "h:mm:ss am/pm", "3:30:00 pm"}, diff --git a/rows.go b/rows.go index 4470d2e1..6b44d8a2 100644 --- a/rows.go +++ b/rows.go @@ -138,7 +138,7 @@ func (rows *Rows) Columns(opts ...Options) ([]string, error) { } var rowIterator rowXMLIterator var token xml.Token - rows.rawCellValue = parseOptions(opts...).RawCellValue + rows.rawCellValue = getOptions(opts...).RawCellValue if rows.sst, rowIterator.err = rows.f.sharedStringsReader(); rowIterator.err != nil { return rowIterator.cells, rowIterator.err } diff --git a/rows_test.go b/rows_test.go index 20b7a893..95e59d99 100644 --- a/rows_test.go +++ b/rows_test.go @@ -1052,6 +1052,8 @@ func TestNumberFormats(t *testing.T) { assert.NoError(t, err) numFmt10, err := f.NewStyle(&Style{NumFmt: 10}) assert.NoError(t, err) + numFmt21, err := f.NewStyle(&Style{NumFmt: 21}) + assert.NoError(t, err) numFmt37, err := f.NewStyle(&Style{NumFmt: 37}) assert.NoError(t, err) numFmt38, err := f.NewStyle(&Style{NumFmt: 38}) @@ -1093,6 +1095,9 @@ func TestNumberFormats(t *testing.T) { {"A30", numFmt40, -8.8888666665555493e+19, "(88,888,666,665,555,500,000.00)"}, {"A31", numFmt40, 8.8888666665555487, "8.89 "}, {"A32", numFmt40, -8.8888666665555487, "(8.89)"}, + {"A33", numFmt21, 44729.999988368058, "23:59:59"}, + {"A34", numFmt21, 44944.375005787035, "09:00:00"}, + {"A35", numFmt21, 44944.375005798611, "09:00:01"}, } { cell, styleID, value, expected := cases[0].(string), cases[1].(int), cases[2], cases[3].(string) assert.NoError(t, f.SetCellStyle("Sheet1", cell, cell, styleID))