forked from qax-os/excelize
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Formatted cell data support, fix issue qax-os#48;
- Function `SetCellValue()` support `time.Time` data type parameter, relate issue qax-os#49; - go doc and go test updated
- Loading branch information
Showing
6 changed files
with
357 additions
and
13 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,119 @@ | ||
package excelize | ||
|
||
import ( | ||
"math" | ||
"time" | ||
) | ||
|
||
// 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++ | ||
julianFraction -= 0.5 | ||
case julianFraction <= -0.5: | ||
julianDays-- | ||
julianFraction += 1.5 | ||
} | ||
return julianDays, julianFraction | ||
} | ||
|
||
// 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) { | ||
|
||
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) | ||
julianDays := part1I + part2I | ||
julianFraction := part1F + part2F | ||
julianDays, julianFraction = shiftJulianToNoon(julianDays, julianFraction) | ||
day, month, year := doTheFliegelAndVanFlandernAlgorithm(int(julianDays)) | ||
hours, minutes, seconds, nanoseconds := fractionOfADay(julianFraction) | ||
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. | ||
func doTheFliegelAndVanFlandernAlgorithm(jd int) (day, month, year int) { | ||
l := jd + 68569 | ||
n := (4 * l) / 146097 | ||
l = l - (146097*n+3)/4 | ||
i := (4000 * (l + 1)) / 1461001 | ||
l = l - (1461*i)/4 + 31 | ||
j := (80 * l) / 2447 | ||
d := l - (2447*j)/80 | ||
l = j / 11 | ||
m := j + 2 - (12 * l) | ||
y := 100*(n-49) + i + l | ||
return d, m, y | ||
} | ||
|
||
// 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(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(MJD0, excelTime+OFFSET1904) | ||
} else { | ||
date = julianDateToGregorianTime(MJD0, excelTime+OFFSET1900) | ||
} | ||
return date | ||
} | ||
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) | ||
} else { | ||
date = time.Date(1899, 12, 30, 0, 0, 0, 0, time.UTC) | ||
} | ||
durationDays := time.Duration(intPart) * time.Hour * 24 | ||
durationPart := time.Duration(dayNanoSeconds * floatPart) | ||
return date.Add(durationDays).Add(durationPart) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.