diff options
author | xuri <xuri.me@gmail.com> | 2018-09-27 23:40:00 +0800 |
---|---|---|
committer | GitHub <noreply@github.com> | 2018-09-27 23:40:00 +0800 |
commit | 204139739a34aa6e6c5ea8764008276a6d184ff6 (patch) | |
tree | 0b9a795ea20804753134fd54c40d17c5a01c64f6 /date.go | |
parent | 250946568ca1e5a69c07f19dff4d1d3a2264e31d (diff) | |
parent | 3e004d900b103379c2d62657a3070de4a2e8585a (diff) |
Merge branch 'master' into master
Diffstat (limited to 'date.go')
-rw-r--r-- | date.go | 59 |
1 files changed, 45 insertions, 14 deletions
@@ -1,3 +1,12 @@ +// Copyright 2016 - 2018 The excelize Authors. All rights reserved. Use of +// this source code is governed by a BSD-style license that can be found in +// the LICENSE file. +// +// Package excelize providing a set of functions that allow you to write to +// and read from XLSX files. Support reads and writes XLSX file generated by +// Microsoft Excelâ„¢ 2007 and later. Support save file without losing original +// charts of XLSX. This library needs Go version 1.8 or later. + package excelize import ( @@ -8,17 +17,31 @@ import ( // timeLocationUTC defined the UTC time location. var timeLocationUTC, _ = time.LoadLocation("UTC") -// timeToUTCTime provides function to convert time to UTC time. +// timeToUTCTime provides a function to convert time to UTC time. func timeToUTCTime(t time.Time) time.Time { return time.Date(t.Year(), t.Month(), t.Day(), t.Hour(), t.Minute(), t.Second(), t.Nanosecond(), timeLocationUTC) } -// timeToExcelTime provides function to convert time to Excel time. +// timeToExcelTime provides a function to convert time to Excel time. func timeToExcelTime(t time.Time) float64 { - return float64(t.UnixNano())/8.64e13 + 25569.0 + // TODO in future this should probably also handle date1904 and like TimeFromExcelTime + var excelTime float64 + var deltaDays int64 + excelTime = 0 + deltaDays = 290 * 364 + // check if UnixNano would be out of int64 range + for t.Unix() > deltaDays*24*60*60 { + // reduce by aprox. 290 years, which is max for int64 nanoseconds + delta := time.Duration(deltaDays) * 24 * time.Hour + excelTime = excelTime + float64(deltaDays) + t = t.Add(-delta) + } + // finally add remainder of UnixNano to keep nano precision + // and 25569 which is days between 1900 and 1970 + return excelTime + float64(t.UnixNano())/8.64e13 + 25569.0 } -// shiftJulianToNoon provides function to process julian date to noon. +// shiftJulianToNoon provides a function to process julian date to noon. func shiftJulianToNoon(julianDays, julianFraction float64) (float64, float64) { switch { case -0.5 < julianFraction && julianFraction < 0.5: @@ -33,7 +56,7 @@ func shiftJulianToNoon(julianDays, julianFraction float64) (float64, float64) { return julianDays, julianFraction } -// fractionOfADay provides function to return the integer values for hour, +// fractionOfADay provides a function to return the integer values for hour, // minutes, seconds and nanoseconds that comprised a given fraction of a day. // values would round to 1 us. func fractionOfADay(fraction float64) (hours, minutes, seconds, nanoseconds int) { @@ -54,7 +77,7 @@ func fractionOfADay(fraction float64) (hours, minutes, seconds, nanoseconds int) return } -// julianDateToGregorianTime provides function to convert julian date to +// julianDateToGregorianTime provides a function to convert julian date to // gregorian time. func julianDateToGregorianTime(part1, part2 float64) time.Time { part1I, part1F := math.Modf(part1) @@ -67,12 +90,12 @@ func julianDateToGregorianTime(part1, part2 float64) time.Time { return time.Date(year, time.Month(month), day, hours, minutes, seconds, nanoseconds, time.UTC) } -// By this point generations of programmers have repeated the algorithm sent to -// the editor of "Communications of the ACM" in 1968 (published in CACM, volume -// 11, number 10, October 1968, p.657). None of those programmers seems to have -// found it necessary to explain the constants or variable names set out by -// Henry F. Fliegel and Thomas C. Van Flandern. Maybe one day I'll buy that -// jounal and expand an explanation here - that day is not today. +// By this point generations of programmers have repeated the algorithm sent +// to the editor of "Communications of the ACM" in 1968 (published in CACM, +// volume 11, number 10, October 1968, p.657). None of those programmers seems +// to have found it necessary to explain the constants or variable names set +// out by Henry F. Fliegel and Thomas C. Van Flandern. Maybe one day I'll buy +// that jounal and expand an explanation here - that day is not today. func doTheFliegelAndVanFlandernAlgorithm(jd int) (day, month, year int) { l := jd + 68569 n := (4 * l) / 146097 @@ -87,9 +110,10 @@ func doTheFliegelAndVanFlandernAlgorithm(jd int) (day, month, year int) { return d, m, y } -// timeFromExcelTime provides function to convert an excelTime representation -// (stored as a floating point number) to a time.Time. +// 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) // Excel uses Julian dates prior to March 1st 1900, and Gregorian @@ -113,6 +137,13 @@ func timeFromExcelTime(excelTime float64, date1904 bool) time.Time { } else { date = time.Date(1899, 12, 30, 0, 0, 0, 0, time.UTC) } + + // 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) |