summaryrefslogtreecommitdiff
path: root/date.go
diff options
context:
space:
mode:
authorxuri <xuri.me@gmail.com>2018-09-27 23:40:00 +0800
committerGitHub <noreply@github.com>2018-09-27 23:40:00 +0800
commit204139739a34aa6e6c5ea8764008276a6d184ff6 (patch)
tree0b9a795ea20804753134fd54c40d17c5a01c64f6 /date.go
parent250946568ca1e5a69c07f19dff4d1d3a2264e31d (diff)
parent3e004d900b103379c2d62657a3070de4a2e8585a (diff)
Merge branch 'master' into master
Diffstat (limited to 'date.go')
-rw-r--r--date.go59
1 files changed, 45 insertions, 14 deletions
diff --git a/date.go b/date.go
index a493866..45f3040 100644
--- a/date.go
+++ b/date.go
@@ -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)