DATE_DIFF_MILLIS calculate wrong result with 'millisecond' option


#1

Sometime DATE_DIFF_MILLIS calculate wrong result as follows
DATE_DIFF_MILLIS(1465634581881,1465634581880,‘millisecond’)

This result was 0. but obviously, it should be 1.

I found something wrong from source code.
https://github.com/couchbase/query/blob/master/expression/func_date.go,

343: 	da1 := date1.Actual().(float64)
344: 	da2 := date2.Actual().(float64)
345: 	pa := part.Actual().(string)
346: 	diff, err := dateDiff(millisToTime(da1), millisToTime(da2), pa)

In this case date1 is 1465634581881 and date2 is 1465634581880.

from source code, da1 is changed to float64 format
da1 => 1.465634581881e+12
da2 => 1.46563458188e+12

And then set to millisToTime function

1440:        func millisToTime(millis float64) time.Time {
1441:       	return time.Unix(0, int64(millis*1000000.0))
1442:        }

… change float64 to int64 and multiply 1000000.0 to change nano_sec from milli_sec.

int64(da11000000.0) => 1465634581880999936
int64(da2
1000000.0) => 1465634581880000000

dateDiff function is mainly calling diffDates function

diffDates main part is…

1758:	setDate(&d1, t1)
1759:	setDate(&d2, t2)
1760:
1761:	diff.millisecond = d1.millisecond - d2.millisecond

setDate is…

1791:       func setDate(d *date, t time.Time) {
1792:	    d.year = t.Year()
1793:	    d.doy = t.YearDay()
1794:	    d.hour, d.minute, d.second = t.Clock()
1795:	    d.millisecond = t.Nanosecond() / 1000000
1796:       }

It’s divide Nanosecond by 1000000

time.Unix(0,int64(da11000000.0) ).Nanosecond()/1000000 => 880
time.Unix(0,int64(da2
1000000.0) ).Nanosecond()/1000000 => 880

It’s typical round-off error!!

Fix it!


#2

Thank you! We will take a look.