Browse Source

Merge pull request #274 from ds0nt/master

Can output times and dates with custom formats and timezones.
Geoffrey J. Teale 8 years ago
parent
commit
187aa939b7
2 changed files with 67 additions and 2 deletions
  1. 32 2
      cell.go
  2. 35 0
      cell_test.go

+ 32 - 2
cell.go

@@ -122,13 +122,43 @@ func TimeToExcelTime(t time.Time) float64 {
 	return float64(t.UnixNano())/8.64e13 + 25569.0
 }
 
+// DateTimeOptions are additional options for exporting times
+type DateTimeOptions struct {
+	// Location allows calculating times in other timezones/locations
+	Location *time.Location
+	// ExcelTimeFormat is the string you want excel to use to format the datetime
+	ExcelTimeFormat string
+}
+
+var (
+	DefaultDateFormat     = builtInNumFmt[14]
+	DefaultDateTimeFormat = builtInNumFmt[22]
+
+	DefaultDateOptions = DateTimeOptions{
+		Location:        timeLocationUTC,
+		ExcelTimeFormat: DefaultDateFormat,
+	}
+
+	DefaultDateTimeOptions = DateTimeOptions{
+		Location:        timeLocationUTC,
+		ExcelTimeFormat: DefaultDateTimeFormat,
+	}
+)
+
 // SetDate sets the value of a cell to a float.
 func (c *Cell) SetDate(t time.Time) {
-	c.SetDateTimeWithFormat(float64(int64(TimeToExcelTime(TimeToUTCTime(t)))), builtInNumFmt[14])
+	c.SetDateWithOptions(t, DefaultDateOptions)
 }
 
 func (c *Cell) SetDateTime(t time.Time) {
-	c.SetDateTimeWithFormat(TimeToExcelTime(TimeToUTCTime(t)), builtInNumFmt[22])
+	c.SetDateWithOptions(t, DefaultDateTimeOptions)
+}
+
+// SetDateWithOptions allows for more granular control when exporting dates and times
+func (c *Cell) SetDateWithOptions(t time.Time, options DateTimeOptions) {
+	_, offset := t.In(options.Location).Zone()
+	t = time.Unix(t.Unix()+int64(offset), 0)
+	c.SetDateTimeWithFormat(TimeToExcelTime(t.In(timeLocationUTC)), options.ExcelTimeFormat)
 }
 
 func (c *Cell) SetDateTimeWithFormat(n float64, format string) {

+ 35 - 0
cell_test.go

@@ -501,6 +501,41 @@ func (s *CellSuite) TestSetValue(c *C) {
 	c.Assert(cell.Value, Equals, "[test]")
 }
 
+func (s *CellSuite) TestSetDateWithOptions(c *C) {
+	cell := Cell{}
+
+	// time
+	cell.SetDate(time.Unix(0, 0))
+	val, err := cell.Float()
+	c.Assert(err, IsNil)
+	c.Assert(math.Floor(val), Equals, 25569.0)
+
+	// our test subject
+	date2016UTC := time.Date(2016, 1, 1, 12, 0, 0, 0, time.UTC)
+
+	// test ny timezone
+	nyTZ, err := time.LoadLocation("America/New_York")
+	c.Assert(err, IsNil)
+	cell.SetDateWithOptions(date2016UTC, DateTimeOptions{
+		ExcelTimeFormat: "test_format1",
+		Location:        nyTZ,
+	})
+	val, err = cell.Float()
+	c.Assert(err, IsNil)
+	c.Assert(val, Equals, TimeToExcelTime(time.Date(2016, 1, 1, 7, 0, 0, 0, time.UTC)))
+
+	// test jp timezone
+	jpTZ, err := time.LoadLocation("Asia/Tokyo")
+	c.Assert(err, IsNil)
+	cell.SetDateWithOptions(date2016UTC, DateTimeOptions{
+		ExcelTimeFormat: "test_format2",
+		Location:        jpTZ,
+	})
+	val, err = cell.Float()
+	c.Assert(err, IsNil)
+	c.Assert(val, Equals, TimeToExcelTime(time.Date(2016, 1, 1, 21, 0, 0, 0, time.UTC)))
+}
+
 func (s *CellSuite) TestIsTimeFormat(c *C) {
 	c.Assert(isTimeFormat("yy"), Equals, true)
 	c.Assert(isTimeFormat("hh"), Equals, true)