Browse Source

Merge pull request #242 from santsai/date_fix

Incorrect parsed date fix
Geoffrey J. Teale 9 years ago
parent
commit
798f401ee4
4 changed files with 51 additions and 30 deletions
  1. 0 1
      cell.go
  2. 28 18
      cell_test.go
  3. 16 9
      date.go
  4. 7 2
      date_test.go

+ 0 - 1
cell.go

@@ -384,7 +384,6 @@ func parseTime(c *Cell) (string, error) {
 		{"mm", "01"},
 		{"mm", "01"},
 		{"am/pm", "pm"},
 		{"am/pm", "pm"},
 		{"m/", "1/"},
 		{"m/", "1/"},
-		{".0", ".9999"},
 		{"%%%%", "January"},
 		{"%%%%", "January"},
 		{"&&&&", "Monday"},
 		{"&&&&", "Monday"},
 	}
 	}

+ 28 - 18
cell_test.go

@@ -231,21 +231,21 @@ func (l *CellSuite) TestFormattedValue(c *C) {
 	cell.NumFmt = "h:mm am/pm"
 	cell.NumFmt = "h:mm am/pm"
 	fvc.Equals(cell, "6:00 pm")
 	fvc.Equals(cell, "6:00 pm")
 	smallCell.NumFmt = "h:mm am/pm"
 	smallCell.NumFmt = "h:mm am/pm"
-	fvc.Equals(smallCell, "12:14 am")
+	fvc.Equals(smallCell, "12:10 am")
 
 
 	cell.NumFmt = "h:mm:ss am/pm"
 	cell.NumFmt = "h:mm:ss am/pm"
 	fvc.Equals(cell, "6:00:00 pm")
 	fvc.Equals(cell, "6:00:00 pm")
 	cell.NumFmt = "hh:mm:ss"
 	cell.NumFmt = "hh:mm:ss"
 	fvc.Equals(cell, "18:00:00")
 	fvc.Equals(cell, "18:00:00")
 	smallCell.NumFmt = "h:mm:ss am/pm"
 	smallCell.NumFmt = "h:mm:ss am/pm"
-	fvc.Equals(smallCell, "12:14:47 am")
+	fvc.Equals(smallCell, "12:10:04 am")
 
 
 	cell.NumFmt = "h:mm"
 	cell.NumFmt = "h:mm"
 	fvc.Equals(cell, "6:00")
 	fvc.Equals(cell, "6:00")
 	smallCell.NumFmt = "h:mm"
 	smallCell.NumFmt = "h:mm"
-	fvc.Equals(smallCell, "12:14")
+	fvc.Equals(smallCell, "12:10")
 	smallCell.NumFmt = "hh:mm"
 	smallCell.NumFmt = "hh:mm"
-	fvc.Equals(smallCell, "00:14")
+	fvc.Equals(smallCell, "00:10")
 
 
 	cell.NumFmt = "h:mm:ss"
 	cell.NumFmt = "h:mm:ss"
 	fvc.Equals(cell, "6:00:00")
 	fvc.Equals(cell, "6:00:00")
@@ -253,18 +253,18 @@ func (l *CellSuite) TestFormattedValue(c *C) {
 	fvc.Equals(cell, "18:00:00")
 	fvc.Equals(cell, "18:00:00")
 
 
 	smallCell.NumFmt = "hh:mm:ss"
 	smallCell.NumFmt = "hh:mm:ss"
-	fvc.Equals(smallCell, "00:14:47")
+	fvc.Equals(smallCell, "00:10:04")
 	smallCell.NumFmt = "h:mm:ss"
 	smallCell.NumFmt = "h:mm:ss"
-	fvc.Equals(smallCell, "12:14:47")
+	fvc.Equals(smallCell, "12:10:04")
 
 
 	cell.NumFmt = "m/d/yy h:mm"
 	cell.NumFmt = "m/d/yy h:mm"
 	fvc.Equals(cell, "11/22/03 6:00")
 	fvc.Equals(cell, "11/22/03 6:00")
 	cell.NumFmt = "m/d/yy hh:mm"
 	cell.NumFmt = "m/d/yy hh:mm"
 	fvc.Equals(cell, "11/22/03 18:00")
 	fvc.Equals(cell, "11/22/03 18:00")
 	smallCell.NumFmt = "m/d/yy h:mm"
 	smallCell.NumFmt = "m/d/yy h:mm"
-	fvc.Equals(smallCell, "12/30/99 12:14")
+	fvc.Equals(smallCell, "12/30/99 12:10")
 	smallCell.NumFmt = "m/d/yy hh:mm"
 	smallCell.NumFmt = "m/d/yy hh:mm"
-	fvc.Equals(smallCell, "12/30/99 00:14")
+	fvc.Equals(smallCell, "12/30/99 00:10")
 	earlyCell.NumFmt = "m/d/yy hh:mm"
 	earlyCell.NumFmt = "m/d/yy hh:mm"
 	fvc.Equals(earlyCell, "1/1/00 02:24")
 	fvc.Equals(earlyCell, "1/1/00 02:24")
 	earlyCell.NumFmt = "m/d/yy h:mm"
 	earlyCell.NumFmt = "m/d/yy h:mm"
@@ -273,19 +273,29 @@ func (l *CellSuite) TestFormattedValue(c *C) {
 	cell.NumFmt = "mm:ss"
 	cell.NumFmt = "mm:ss"
 	fvc.Equals(cell, "00:00")
 	fvc.Equals(cell, "00:00")
 	smallCell.NumFmt = "mm:ss"
 	smallCell.NumFmt = "mm:ss"
-	fvc.Equals(smallCell, "14:47")
+	fvc.Equals(smallCell, "10:04")
 
 
 	cell.NumFmt = "[hh]:mm:ss"
 	cell.NumFmt = "[hh]:mm:ss"
 	fvc.Equals(cell, "18:00:00")
 	fvc.Equals(cell, "18:00:00")
 	cell.NumFmt = "[h]:mm:ss"
 	cell.NumFmt = "[h]:mm:ss"
 	fvc.Equals(cell, "6:00:00")
 	fvc.Equals(cell, "6:00:00")
 	smallCell.NumFmt = "[h]:mm:ss"
 	smallCell.NumFmt = "[h]:mm:ss"
-	fvc.Equals(smallCell, "14:47")
-
-	cell.NumFmt = "mmss.0" // I'm not sure about these.
-	fvc.Equals(cell, "0000.0086")
-	smallCell.NumFmt = "mmss.0"
-	fvc.Equals(smallCell, "1447.9999")
+	fvc.Equals(smallCell, "10:04")
+
+	const (
+		expect1 = "0000.0086"
+		expect2 = "1004.8000"
+		format  = "mmss.0000"
+		tlen    = len(format)
+	)
+
+	for i := 0; i < 3; i++ {
+		tfmt := format[0 : tlen-i]
+		cell.NumFmt = tfmt
+		fvc.Equals(cell, expect1[0:tlen-i])
+		smallCell.NumFmt = tfmt
+		fvc.Equals(smallCell, expect2[0:tlen-i])
+	}
 
 
 	cell.NumFmt = "yyyy\\-mm\\-dd"
 	cell.NumFmt = "yyyy\\-mm\\-dd"
 	fvc.Equals(cell, "2003\\-11\\-22")
 	fvc.Equals(cell, "2003\\-11\\-22")
@@ -301,7 +311,7 @@ func (l *CellSuite) TestFormattedValue(c *C) {
 	cell.NumFmt = "hh:mm:ss"
 	cell.NumFmt = "hh:mm:ss"
 	fvc.Equals(cell, "18:00:00")
 	fvc.Equals(cell, "18:00:00")
 	smallCell.NumFmt = "hh:mm:ss"
 	smallCell.NumFmt = "hh:mm:ss"
-	fvc.Equals(smallCell, "00:14:47")
+	fvc.Equals(smallCell, "00:10:04")
 
 
 	cell.NumFmt = "dd/mm/yy\\ hh:mm"
 	cell.NumFmt = "dd/mm/yy\\ hh:mm"
 	fvc.Equals(cell, "22/11/03\\ 18:00")
 	fvc.Equals(cell, "22/11/03\\ 18:00")
@@ -341,12 +351,12 @@ func (l *CellSuite) TestFormattedValue(c *C) {
 	cell.NumFmt = "mm/dd/yyyy hh:mm:ss"
 	cell.NumFmt = "mm/dd/yyyy hh:mm:ss"
 	fvc.Equals(cell, "11/22/2003 18:00:00")
 	fvc.Equals(cell, "11/22/2003 18:00:00")
 	smallCell.NumFmt = "mm/dd/yyyy hh:mm:ss"
 	smallCell.NumFmt = "mm/dd/yyyy hh:mm:ss"
-	fvc.Equals(smallCell, "12/30/1899 00:14:47")
+	fvc.Equals(smallCell, "12/30/1899 00:10:04")
 
 
 	cell.NumFmt = "yyyy-mm-dd hh:mm:ss"
 	cell.NumFmt = "yyyy-mm-dd hh:mm:ss"
 	fvc.Equals(cell, "2003-11-22 18:00:00")
 	fvc.Equals(cell, "2003-11-22 18:00:00")
 	smallCell.NumFmt = "yyyy-mm-dd hh:mm:ss"
 	smallCell.NumFmt = "yyyy-mm-dd hh:mm:ss"
-	fvc.Equals(smallCell, "1899-12-30 00:14:47")
+	fvc.Equals(smallCell, "1899-12-30 00:10:04")
 
 
 	cell.NumFmt = "mmmm d, yyyy"
 	cell.NumFmt = "mmmm d, yyyy"
 	fvc.Equals(cell, "November 22, 2003")
 	fvc.Equals(cell, "November 22, 2003")

+ 16 - 9
date.go

@@ -24,16 +24,23 @@ func shiftJulianToNoon(julianDays, julianFraction float64) (float64, float64) {
 
 
 // Return the integer values for hour, minutes, seconds and
 // Return the integer values for hour, minutes, seconds and
 // nanoseconds that comprised a given fraction of a day.
 // nanoseconds that comprised a given fraction of a day.
+// values would round to 1 us.
 func fractionOfADay(fraction float64) (hours, minutes, seconds, nanoseconds int) {
 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, 3600))
-	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
 }
 }
 
 
 func julianDateToGregorianTime(part1, part2 float64) time.Time {
 func julianDateToGregorianTime(part1, part2 float64) time.Time {

+ 7 - 2
date_test.go

@@ -29,9 +29,14 @@ func (d *DateSuite) TestJulianDateToGregorianTime(c *C) {
 	c.Assert(julianDateToGregorianTime(2400000.5, 51544.5),
 	c.Assert(julianDateToGregorianTime(2400000.5, 51544.5),
 		Equals, time.Date(2000, 1, 1, 12, 0, 0, 0, time.UTC))
 		Equals, time.Date(2000, 1, 1, 12, 0, 0, 0, time.UTC))
 	c.Assert(julianDateToGregorianTime(2400000.5, 51544.245),
 	c.Assert(julianDateToGregorianTime(2400000.5, 51544.245),
-		Equals, time.Date(2000, 1, 1, 6, 40, 0, 13578, time.UTC))
+		Equals, time.Date(2000, 1, 1, 5, 52, 48, 0, time.UTC))
+	c.Assert(julianDateToGregorianTime(2400000.5, 51544.2456),
+		Equals, time.Date(2000, 1, 1, 5, 53, 39, 840000000, time.UTC))
+	/* test rounding: 0.24560789123*24*3600 = 21220.521802272 */
+	c.Assert(julianDateToGregorianTime(2400000.5, 51544.24560789123),
+		Equals, time.Date(2000, 1, 1, 5, 53, 40, 521802000, time.UTC))
 	c.Assert(julianDateToGregorianTime(2400000.5, 51544.1),
 	c.Assert(julianDateToGregorianTime(2400000.5, 51544.1),
-		Equals, time.Date(2000, 1, 1, 3, 22, 59, 999992456, time.UTC))
+		Equals, time.Date(2000, 1, 1, 2, 24, 00, 0, time.UTC))
 	c.Assert(julianDateToGregorianTime(2400000.5, 51544.75),
 	c.Assert(julianDateToGregorianTime(2400000.5, 51544.75),
 		Equals, time.Date(2000, 1, 1, 18, 0, 0, 0, time.UTC))
 		Equals, time.Date(2000, 1, 1, 18, 0, 0, 0, time.UTC))
 }
 }