Add Formula & Format support
This commit is contained in:
79
date.go
79
date.go
@@ -5,37 +5,57 @@ import (
|
||||
"time"
|
||||
)
|
||||
|
||||
const MJD_0 float64 = 2400000.5
|
||||
const MJD_JD2000 float64 = 51544.5
|
||||
// timeLocationUTC defined the UTC time location.
|
||||
var timeLocationUTC, _ = time.LoadLocation("UTC")
|
||||
|
||||
// timeToUTCTime provides 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.
|
||||
func timeToExcelTime(t time.Time) float64 {
|
||||
return float64(t.UnixNano())/8.64e13 + 25569.0
|
||||
}
|
||||
|
||||
// shiftJulianToNoon provides function to process julian date to noon.
|
||||
func shiftJulianToNoon(julianDays, julianFraction float64) (float64, float64) {
|
||||
switch {
|
||||
case -0.5 < julianFraction && julianFraction < 0.5:
|
||||
julianFraction += 0.5
|
||||
case julianFraction >= 0.5:
|
||||
julianDays += 1
|
||||
julianDays++
|
||||
julianFraction -= 0.5
|
||||
case julianFraction <= -0.5:
|
||||
julianDays -= 1
|
||||
julianDays--
|
||||
julianFraction += 1.5
|
||||
}
|
||||
return julianDays, julianFraction
|
||||
}
|
||||
|
||||
// Return the integer values for hour, minutes, seconds and
|
||||
// nanoseconds that comprised a given fraction of a day.
|
||||
// fractionOfADay provides 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) {
|
||||
f := 5184000000000000 * fraction
|
||||
nanoseconds = int(math.Mod(f, 1000000000))
|
||||
f = f / 1000000000
|
||||
seconds = int(math.Mod(f, 60))
|
||||
f = f / 3600
|
||||
minutes = int(math.Mod(f, 60))
|
||||
f = f / 60
|
||||
hours = int(f)
|
||||
return hours, minutes, seconds, nanoseconds
|
||||
|
||||
const (
|
||||
c1us = 1e3
|
||||
c1s = 1e9
|
||||
c1day = 24 * 60 * 60 * c1s
|
||||
)
|
||||
|
||||
frac := int64(c1day*fraction + c1us/2)
|
||||
nanoseconds = int((frac%c1s)/c1us) * c1us
|
||||
frac /= c1s
|
||||
seconds = int(frac % 60)
|
||||
frac /= 60
|
||||
minutes = int(frac % 60)
|
||||
hours = int(frac / 60)
|
||||
return
|
||||
}
|
||||
|
||||
// julianDateToGregorianTime provides function to convert julian date to
|
||||
// gregorian time.
|
||||
func julianDateToGregorianTime(part1, part2 float64) time.Time {
|
||||
part1I, part1F := math.Modf(part1)
|
||||
part2I, part2F := math.Modf(part2)
|
||||
@@ -47,13 +67,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
|
||||
@@ -68,24 +87,26 @@ func doTheFliegelAndVanFlandernAlgorithm(jd int) (day, month, year int) {
|
||||
return d, m, y
|
||||
}
|
||||
|
||||
// Convert an excelTime representation (stored as a floating point number) to a time.Time.
|
||||
// timeFromExcelTime provides function to convert an excelTime representation
|
||||
// (stored as a floating point number) to a time.Time.
|
||||
func timeFromExcelTime(excelTime float64, date1904 bool) time.Time {
|
||||
var date time.Time
|
||||
var intPart int64 = int64(excelTime)
|
||||
// Excel uses Julian dates prior to March 1st 1900, and
|
||||
// Gregorian thereafter.
|
||||
var intPart = int64(excelTime)
|
||||
// Excel uses Julian dates prior to March 1st 1900, and Gregorian
|
||||
// thereafter.
|
||||
if intPart <= 61 {
|
||||
const OFFSET1900 = 15018.0
|
||||
const OFFSET1904 = 16480.0
|
||||
const MJD0 float64 = 2400000.5
|
||||
var date time.Time
|
||||
if date1904 {
|
||||
date = julianDateToGregorianTime(MJD_0+OFFSET1904, excelTime)
|
||||
date = julianDateToGregorianTime(MJD0, excelTime+OFFSET1904)
|
||||
} else {
|
||||
date = julianDateToGregorianTime(MJD_0+OFFSET1900, excelTime)
|
||||
date = julianDateToGregorianTime(MJD0, excelTime+OFFSET1900)
|
||||
}
|
||||
return date
|
||||
}
|
||||
var floatPart float64 = excelTime - float64(intPart)
|
||||
var floatPart = excelTime - float64(intPart)
|
||||
var dayNanoSeconds float64 = 24 * 60 * 60 * 1000 * 1000 * 1000
|
||||
if date1904 {
|
||||
date = time.Date(1904, 1, 1, 0, 0, 0, 0, time.UTC)
|
||||
|
||||
Reference in New Issue
Block a user