Skip to content

Commit

Permalink
This closes qax-os#1030, fix date rounding error
Browse files Browse the repository at this point in the history
  • Loading branch information
xuri committed Oct 11, 2021
1 parent 13dd6de commit 69af35b
Show file tree
Hide file tree
Showing 2 changed files with 17 additions and 2 deletions.
5 changes: 3 additions & 2 deletions date.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ const (
nanosInADay = float64((24 * time.Hour) / time.Nanosecond)
dayNanoseconds = 24 * time.Hour
maxDuration = 290 * 364 * dayNanoseconds
roundEpsilon = 1e-9
)

var (
Expand Down Expand Up @@ -151,14 +152,14 @@ func timeFromExcelTime(excelTime float64, date1904 bool) time.Time {
}
return date
}
var floatPart = excelTime - float64(wholeDaysPart)
var floatPart = excelTime - float64(wholeDaysPart) + roundEpsilon
if date1904 {
date = excel1904Epoc
} else {
date = excel1900Epoc
}
durationPart := time.Duration(nanosInADay * floatPart)
return date.AddDate(0, 0, wholeDaysPart).Add(durationPart)
return date.AddDate(0, 0, wholeDaysPart).Add(durationPart).Truncate(time.Second)
}

// ExcelDateToTime converts a float-based excel date representation to a time.Time.
Expand Down
14 changes: 14 additions & 0 deletions date_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ var excelTimeInputList = []dateTest{
{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)},
{44450.3333333333, time.Date(2021, time.September, 11, 8, 0, 0, 0, time.UTC)},
{401769.0, time.Date(3000, 1, 1, 0, 0, 0, 0, time.UTC)},
}

Expand Down Expand Up @@ -66,6 +67,19 @@ func TestTimeFromExcelTime(t *testing.T) {
assert.Equal(t, test.GoValue, timeFromExcelTime(test.ExcelValue, false))
})
}
for hour := 0; hour < 24; hour++ {
for min := 0; min < 60; min++ {
for sec := 0; sec < 60; sec++ {
date := time.Date(2021, time.December, 30, hour, min, sec, 0, time.UTC)
excelTime, err := timeToExcelTime(date)
assert.NoError(t, err)
dateOut := timeFromExcelTime(excelTime, false)
assert.EqualValues(t, hour, dateOut.Hour())
assert.EqualValues(t, min, dateOut.Minute())
assert.EqualValues(t, sec, dateOut.Second())
}
}
}
}

func TestTimeFromExcelTime_1904(t *testing.T) {
Expand Down

0 comments on commit 69af35b

Please sign in to comment.