From 7dbf88f221f278075d4ff9e153b21236d0826c33 Mon Sep 17 00:00:00 2001 From: xuri Date: Thu, 29 Jul 2021 00:03:57 +0800 Subject: This closes #971, closes #972 and closes #974 - Escape XML character in the drop list - Fix incorrect character count limit in the drop list - Fix Excel time parse issue in some case - Fix custom number format month parse issue in some case - Fix corrupted file generated caused by concurrency adding pictures --- date.go | 27 ++++++++++----------------- 1 file changed, 10 insertions(+), 17 deletions(-) (limited to 'date.go') diff --git a/date.go b/date.go index 0531b6c..a5edcf8 100644 --- a/date.go +++ b/date.go @@ -17,11 +17,14 @@ import ( ) const ( + nanosInADay = float64((24 * time.Hour) / time.Nanosecond) dayNanoseconds = 24 * time.Hour maxDuration = 290 * 364 * dayNanoseconds ) var ( + excel1900Epoc = time.Date(1899, time.December, 30, 0, 0, 0, 0, time.UTC) + excel1904Epoc = time.Date(1904, time.January, 1, 0, 0, 0, 0, time.UTC) excelMinTime1900 = time.Date(1899, time.December, 31, 0, 0, 0, 0, time.UTC) excelBuggyPeriodStart = time.Date(1900, time.March, 1, 0, 0, 0, 0, time.UTC).Add(-time.Nanosecond) ) @@ -131,12 +134,11 @@ func doTheFliegelAndVanFlandernAlgorithm(jd int) (day, month, year int) { // timeFromExcelTime provides a function to convert an excelTime // representation (stored as a floating point number) to a time.Time. func timeFromExcelTime(excelTime float64, date1904 bool) time.Time { - const MDD int64 = 106750 // Max time.Duration Days, aprox. 290 years var date time.Time - var intPart = int64(excelTime) + var wholeDaysPart = int(excelTime) // Excel uses Julian dates prior to March 1st 1900, and Gregorian // thereafter. - if intPart <= 61 { + if wholeDaysPart <= 61 { const OFFSET1900 = 15018.0 const OFFSET1904 = 16480.0 const MJD0 float64 = 2400000.5 @@ -148,23 +150,14 @@ func timeFromExcelTime(excelTime float64, date1904 bool) time.Time { } return date } - var floatPart = excelTime - float64(intPart) - var dayNanoSeconds float64 = 24 * 60 * 60 * 1000 * 1000 * 1000 + var floatPart = excelTime - float64(wholeDaysPart) if date1904 { - date = time.Date(1904, 1, 1, 0, 0, 0, 0, time.UTC) + date = excel1904Epoc } else { - date = time.Date(1899, 12, 30, 0, 0, 0, 0, time.UTC) + date = excel1900Epoc } - - // Duration is limited to aprox. 290 years - for intPart > MDD { - durationDays := time.Duration(MDD) * time.Hour * 24 - date = date.Add(durationDays) - intPart = intPart - MDD - } - durationDays := time.Duration(intPart) * time.Hour * 24 - durationPart := time.Duration(dayNanoSeconds * floatPart) - return date.Add(durationDays).Add(durationPart) + durationPart := time.Duration(nanosInADay * floatPart) + return date.AddDate(0, 0, wholeDaysPart).Add(durationPart) } // ExcelDateToTime converts a float-based excel date representation to a time.Time. -- cgit v1.2.1