2018-06-19 20:28:40 +08:00
|
|
|
package excelize
|
|
|
|
|
|
|
|
import (
|
2018-12-27 18:51:44 +08:00
|
|
|
"fmt"
|
2018-09-14 00:24:49 +08:00
|
|
|
"testing"
|
|
|
|
"time"
|
2018-12-27 18:51:44 +08:00
|
|
|
|
|
|
|
"github.com/stretchr/testify/assert"
|
2018-06-19 20:28:40 +08:00
|
|
|
)
|
|
|
|
|
|
|
|
type dateTest struct {
|
2018-09-14 00:24:49 +08:00
|
|
|
ExcelValue float64
|
|
|
|
GoValue time.Time
|
2018-06-19 20:28:40 +08:00
|
|
|
}
|
|
|
|
|
Huge refactorig for consistent col/row numbering (#356)
* Huge refactorig for consistent col/row numbering
Started from simply changing ToALphaString()/TitleToNumber() logic and related fixes.
But have to go deeper, do fixes, after do related fixes and again and again.
Major improvements:
1. Tests made stronger again (But still be weak).
2. "Empty" returns for incorrect input replaces with panic.
3. Check for correct col/row/cell naming & addressing by default.
4. Removed huge amount of duplicated code.
5. Removed ToALphaString(), TitleToNumber() and it helpers functions at all,
and replaced with SplitCellName(), JoinCellName(), ColumnNameToNumber(), ColumnNumberToName(), CellNameToCoordinates(), CoordinatesToCellName().
6. Minor fixes for internal variable naming for code readability (ex. col, row for input params, colIdx, rowIdx for slice indexes etc).
* Formatting fixes
2019-03-20 00:14:41 +08:00
|
|
|
var trueExpectedDateList = []dateTest{
|
|
|
|
{0.0000000000000000, time.Date(1899, time.December, 30, 0, 0, 0, 0, time.UTC)},
|
|
|
|
{25569.000000000000, time.Unix(0, 0).UTC()},
|
|
|
|
|
2020-11-10 23:48:09 +08:00
|
|
|
// Expected values extracted from real spreadsheet
|
Huge refactorig for consistent col/row numbering (#356)
* Huge refactorig for consistent col/row numbering
Started from simply changing ToALphaString()/TitleToNumber() logic and related fixes.
But have to go deeper, do fixes, after do related fixes and again and again.
Major improvements:
1. Tests made stronger again (But still be weak).
2. "Empty" returns for incorrect input replaces with panic.
3. Check for correct col/row/cell naming & addressing by default.
4. Removed huge amount of duplicated code.
5. Removed ToALphaString(), TitleToNumber() and it helpers functions at all,
and replaced with SplitCellName(), JoinCellName(), ColumnNameToNumber(), ColumnNumberToName(), CellNameToCoordinates(), CoordinatesToCellName().
6. Minor fixes for internal variable naming for code readability (ex. col, row for input params, colIdx, rowIdx for slice indexes etc).
* Formatting fixes
2019-03-20 00:14:41 +08:00
|
|
|
{1.0000000000000000, time.Date(1900, time.January, 1, 0, 0, 0, 0, time.UTC)},
|
|
|
|
{1.0000115740740740, time.Date(1900, time.January, 1, 0, 0, 1, 0, time.UTC)},
|
|
|
|
{1.0006944444444446, time.Date(1900, time.January, 1, 0, 1, 0, 0, time.UTC)},
|
|
|
|
{1.0416666666666667, time.Date(1900, time.January, 1, 1, 0, 0, 0, time.UTC)},
|
|
|
|
{2.0000000000000000, time.Date(1900, time.January, 2, 0, 0, 0, 0, time.UTC)},
|
|
|
|
{43269.000000000000, time.Date(2018, time.June, 18, 0, 0, 0, 0, time.UTC)},
|
|
|
|
{43542.611111111109, time.Date(2019, time.March, 18, 14, 40, 0, 0, time.UTC)},
|
|
|
|
{401769.00000000000, time.Date(3000, time.January, 1, 0, 0, 0, 0, time.UTC)},
|
|
|
|
}
|
|
|
|
|
2020-03-03 19:31:02 +08:00
|
|
|
var excelTimeInputList = []dateTest{
|
|
|
|
{0.0, time.Date(1899, 12, 30, 0, 0, 0, 0, time.UTC)},
|
|
|
|
{60.0, time.Date(1900, 2, 28, 0, 0, 0, 0, time.UTC)},
|
|
|
|
{61.0, time.Date(1900, 3, 1, 0, 0, 0, 0, time.UTC)},
|
|
|
|
{41275.0, time.Date(2013, 1, 1, 0, 0, 0, 0, time.UTC)},
|
2021-10-12 00:01:11 +08:00
|
|
|
{44450.3333333333, time.Date(2021, time.September, 11, 8, 0, 0, 0, time.UTC)},
|
2020-03-03 19:31:02 +08:00
|
|
|
{401769.0, time.Date(3000, 1, 1, 0, 0, 0, 0, time.UTC)},
|
|
|
|
}
|
|
|
|
|
2018-06-19 20:28:40 +08:00
|
|
|
func TestTimeToExcelTime(t *testing.T) {
|
Huge refactorig for consistent col/row numbering (#356)
* Huge refactorig for consistent col/row numbering
Started from simply changing ToALphaString()/TitleToNumber() logic and related fixes.
But have to go deeper, do fixes, after do related fixes and again and again.
Major improvements:
1. Tests made stronger again (But still be weak).
2. "Empty" returns for incorrect input replaces with panic.
3. Check for correct col/row/cell naming & addressing by default.
4. Removed huge amount of duplicated code.
5. Removed ToALphaString(), TitleToNumber() and it helpers functions at all,
and replaced with SplitCellName(), JoinCellName(), ColumnNameToNumber(), ColumnNumberToName(), CellNameToCoordinates(), CoordinatesToCellName().
6. Minor fixes for internal variable naming for code readability (ex. col, row for input params, colIdx, rowIdx for slice indexes etc).
* Formatting fixes
2019-03-20 00:14:41 +08:00
|
|
|
for i, test := range trueExpectedDateList {
|
|
|
|
t.Run(fmt.Sprintf("TestData%d", i+1), func(t *testing.T) {
|
2022-05-02 12:30:18 +08:00
|
|
|
excelTime, err := timeToExcelTime(test.GoValue, false)
|
2019-03-23 20:08:06 +08:00
|
|
|
assert.NoError(t, err)
|
|
|
|
assert.Equalf(t, test.ExcelValue, excelTime,
|
Huge refactorig for consistent col/row numbering (#356)
* Huge refactorig for consistent col/row numbering
Started from simply changing ToALphaString()/TitleToNumber() logic and related fixes.
But have to go deeper, do fixes, after do related fixes and again and again.
Major improvements:
1. Tests made stronger again (But still be weak).
2. "Empty" returns for incorrect input replaces with panic.
3. Check for correct col/row/cell naming & addressing by default.
4. Removed huge amount of duplicated code.
5. Removed ToALphaString(), TitleToNumber() and it helpers functions at all,
and replaced with SplitCellName(), JoinCellName(), ColumnNameToNumber(), ColumnNumberToName(), CellNameToCoordinates(), CoordinatesToCellName().
6. Minor fixes for internal variable naming for code readability (ex. col, row for input params, colIdx, rowIdx for slice indexes etc).
* Formatting fixes
2019-03-20 00:14:41 +08:00
|
|
|
"Time: %s", test.GoValue.String())
|
|
|
|
})
|
2018-09-14 00:24:49 +08:00
|
|
|
}
|
Huge refactorig for consistent col/row numbering (#356)
* Huge refactorig for consistent col/row numbering
Started from simply changing ToALphaString()/TitleToNumber() logic and related fixes.
But have to go deeper, do fixes, after do related fixes and again and again.
Major improvements:
1. Tests made stronger again (But still be weak).
2. "Empty" returns for incorrect input replaces with panic.
3. Check for correct col/row/cell naming & addressing by default.
4. Removed huge amount of duplicated code.
5. Removed ToALphaString(), TitleToNumber() and it helpers functions at all,
and replaced with SplitCellName(), JoinCellName(), ColumnNameToNumber(), ColumnNumberToName(), CellNameToCoordinates(), CoordinatesToCellName().
6. Minor fixes for internal variable naming for code readability (ex. col, row for input params, colIdx, rowIdx for slice indexes etc).
* Formatting fixes
2019-03-20 00:14:41 +08:00
|
|
|
}
|
2018-06-19 20:28:40 +08:00
|
|
|
|
Huge refactorig for consistent col/row numbering (#356)
* Huge refactorig for consistent col/row numbering
Started from simply changing ToALphaString()/TitleToNumber() logic and related fixes.
But have to go deeper, do fixes, after do related fixes and again and again.
Major improvements:
1. Tests made stronger again (But still be weak).
2. "Empty" returns for incorrect input replaces with panic.
3. Check for correct col/row/cell naming & addressing by default.
4. Removed huge amount of duplicated code.
5. Removed ToALphaString(), TitleToNumber() and it helpers functions at all,
and replaced with SplitCellName(), JoinCellName(), ColumnNameToNumber(), ColumnNumberToName(), CellNameToCoordinates(), CoordinatesToCellName().
6. Minor fixes for internal variable naming for code readability (ex. col, row for input params, colIdx, rowIdx for slice indexes etc).
* Formatting fixes
2019-03-20 00:14:41 +08:00
|
|
|
func TestTimeToExcelTime_Timezone(t *testing.T) {
|
2019-03-21 14:09:25 +08:00
|
|
|
location, err := time.LoadLocation("America/Los_Angeles")
|
Huge refactorig for consistent col/row numbering (#356)
* Huge refactorig for consistent col/row numbering
Started from simply changing ToALphaString()/TitleToNumber() logic and related fixes.
But have to go deeper, do fixes, after do related fixes and again and again.
Major improvements:
1. Tests made stronger again (But still be weak).
2. "Empty" returns for incorrect input replaces with panic.
3. Check for correct col/row/cell naming & addressing by default.
4. Removed huge amount of duplicated code.
5. Removed ToALphaString(), TitleToNumber() and it helpers functions at all,
and replaced with SplitCellName(), JoinCellName(), ColumnNameToNumber(), ColumnNumberToName(), CellNameToCoordinates(), CoordinatesToCellName().
6. Minor fixes for internal variable naming for code readability (ex. col, row for input params, colIdx, rowIdx for slice indexes etc).
* Formatting fixes
2019-03-20 00:14:41 +08:00
|
|
|
if !assert.NoError(t, err) {
|
|
|
|
t.FailNow()
|
|
|
|
}
|
|
|
|
for i, test := range trueExpectedDateList {
|
2018-12-27 18:51:44 +08:00
|
|
|
t.Run(fmt.Sprintf("TestData%d", i+1), func(t *testing.T) {
|
2022-05-02 12:30:18 +08:00
|
|
|
_, err := timeToExcelTime(test.GoValue.In(location), false)
|
2021-06-04 23:06:58 +08:00
|
|
|
assert.NoError(t, err)
|
2018-12-27 18:51:44 +08:00
|
|
|
})
|
2018-09-14 00:24:49 +08:00
|
|
|
}
|
2018-06-19 20:28:40 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
func TestTimeFromExcelTime(t *testing.T) {
|
2020-03-03 19:31:02 +08:00
|
|
|
for i, test := range excelTimeInputList {
|
2018-12-27 18:51:44 +08:00
|
|
|
t.Run(fmt.Sprintf("TestData%d", i+1), func(t *testing.T) {
|
|
|
|
assert.Equal(t, test.GoValue, timeFromExcelTime(test.ExcelValue, false))
|
|
|
|
})
|
2018-09-14 00:24:49 +08:00
|
|
|
}
|
2021-10-12 00:01:11 +08:00
|
|
|
for hour := 0; hour < 24; hour++ {
|
2024-02-26 02:22:51 +08:00
|
|
|
for minVal := 0; minVal < 60; minVal++ {
|
2021-10-12 00:01:11 +08:00
|
|
|
for sec := 0; sec < 60; sec++ {
|
2024-02-26 02:22:51 +08:00
|
|
|
date := time.Date(2021, time.December, 30, hour, minVal, sec, 0, time.UTC)
|
2022-05-02 12:30:18 +08:00
|
|
|
// Test use 1900 date system
|
|
|
|
excel1900Time, err := timeToExcelTime(date, false)
|
2021-10-12 00:01:11 +08:00
|
|
|
assert.NoError(t, err)
|
2022-05-02 12:30:18 +08:00
|
|
|
date1900Out := timeFromExcelTime(excel1900Time, false)
|
|
|
|
assert.EqualValues(t, hour, date1900Out.Hour())
|
2024-02-26 02:22:51 +08:00
|
|
|
assert.EqualValues(t, minVal, date1900Out.Minute())
|
2022-05-02 12:30:18 +08:00
|
|
|
assert.EqualValues(t, sec, date1900Out.Second())
|
|
|
|
// Test use 1904 date system
|
|
|
|
excel1904Time, err := timeToExcelTime(date, true)
|
|
|
|
assert.NoError(t, err)
|
|
|
|
date1904Out := timeFromExcelTime(excel1904Time, true)
|
|
|
|
assert.EqualValues(t, hour, date1904Out.Hour())
|
2024-02-26 02:22:51 +08:00
|
|
|
assert.EqualValues(t, minVal, date1904Out.Minute())
|
2022-05-02 12:30:18 +08:00
|
|
|
assert.EqualValues(t, sec, date1904Out.Second())
|
2021-10-12 00:01:11 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2018-06-19 20:28:40 +08:00
|
|
|
}
|
Huge refactorig for consistent col/row numbering (#356)
* Huge refactorig for consistent col/row numbering
Started from simply changing ToALphaString()/TitleToNumber() logic and related fixes.
But have to go deeper, do fixes, after do related fixes and again and again.
Major improvements:
1. Tests made stronger again (But still be weak).
2. "Empty" returns for incorrect input replaces with panic.
3. Check for correct col/row/cell naming & addressing by default.
4. Removed huge amount of duplicated code.
5. Removed ToALphaString(), TitleToNumber() and it helpers functions at all,
and replaced with SplitCellName(), JoinCellName(), ColumnNameToNumber(), ColumnNumberToName(), CellNameToCoordinates(), CoordinatesToCellName().
6. Minor fixes for internal variable naming for code readability (ex. col, row for input params, colIdx, rowIdx for slice indexes etc).
* Formatting fixes
2019-03-20 00:14:41 +08:00
|
|
|
|
|
|
|
func TestTimeFromExcelTime_1904(t *testing.T) {
|
2022-05-02 12:30:18 +08:00
|
|
|
julianDays, julianFraction := shiftJulianToNoon(1, -0.6)
|
|
|
|
assert.Equal(t, julianDays, 0.0)
|
|
|
|
assert.Equal(t, julianFraction, 0.9)
|
|
|
|
julianDays, julianFraction = shiftJulianToNoon(1, 0.1)
|
|
|
|
assert.Equal(t, julianDays, 1.0)
|
|
|
|
assert.Equal(t, julianFraction, 0.6)
|
|
|
|
assert.Equal(t, timeFromExcelTime(61, true), time.Date(1904, time.March, 2, 0, 0, 0, 0, time.UTC))
|
|
|
|
assert.Equal(t, timeFromExcelTime(62, true), time.Date(1904, time.March, 3, 0, 0, 0, 0, time.UTC))
|
Huge refactorig for consistent col/row numbering (#356)
* Huge refactorig for consistent col/row numbering
Started from simply changing ToALphaString()/TitleToNumber() logic and related fixes.
But have to go deeper, do fixes, after do related fixes and again and again.
Major improvements:
1. Tests made stronger again (But still be weak).
2. "Empty" returns for incorrect input replaces with panic.
3. Check for correct col/row/cell naming & addressing by default.
4. Removed huge amount of duplicated code.
5. Removed ToALphaString(), TitleToNumber() and it helpers functions at all,
and replaced with SplitCellName(), JoinCellName(), ColumnNameToNumber(), ColumnNumberToName(), CellNameToCoordinates(), CoordinatesToCellName().
6. Minor fixes for internal variable naming for code readability (ex. col, row for input params, colIdx, rowIdx for slice indexes etc).
* Formatting fixes
2019-03-20 00:14:41 +08:00
|
|
|
}
|
2020-03-03 19:31:02 +08:00
|
|
|
|
|
|
|
func TestExcelDateToTime(t *testing.T) {
|
|
|
|
// Check normal case
|
|
|
|
for i, test := range excelTimeInputList {
|
|
|
|
t.Run(fmt.Sprintf("TestData%d", i+1), func(t *testing.T) {
|
|
|
|
timeValue, err := ExcelDateToTime(test.ExcelValue, false)
|
|
|
|
assert.Equal(t, test.GoValue, timeValue)
|
|
|
|
assert.NoError(t, err)
|
|
|
|
})
|
|
|
|
}
|
|
|
|
// Check error case
|
|
|
|
_, err := ExcelDateToTime(-1, false)
|
2021-12-07 00:26:53 +08:00
|
|
|
assert.EqualError(t, err, newInvalidExcelDateError(-1).Error())
|
2020-03-03 19:31:02 +08:00
|
|
|
}
|