Allow converting intervals with months and days to duration

It's a lossy conversion but so is numeric to float.

fixes #42
non-blocking
Jack Christensen 2020-06-20 13:26:06 -05:00
parent 3d6abc3c5b
commit 41a185b611
2 changed files with 15 additions and 4 deletions

View File

@ -16,6 +16,8 @@ const (
microsecondsPerSecond = 1000000
microsecondsPerMinute = 60 * microsecondsPerSecond
microsecondsPerHour = 60 * microsecondsPerMinute
microsecondsPerDay = 24 * microsecondsPerHour
microsecondsPerMonth = 30 * microsecondsPerDay
)
type Interval struct {
@ -67,10 +69,8 @@ func (src *Interval) AssignTo(dst interface{}) error {
case Present:
switch v := dst.(type) {
case *time.Duration:
if src.Days > 0 || src.Months > 0 {
return errors.Errorf("interval with months or days cannot be decoded into %T", dst)
}
*v = time.Duration(src.Microseconds) * time.Microsecond
us := int64(src.Months)*microsecondsPerMonth + int64(src.Days)*microsecondsPerDay + src.Microseconds
*v = time.Duration(us) * time.Microsecond
return nil
default:
if nextDst, retry := GetAssignToDstType(dst); retry {

View File

@ -2,9 +2,12 @@ package pgtype_test
import (
"testing"
"time"
"github.com/jackc/pgtype"
"github.com/jackc/pgtype/testutil"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
)
func TestIntervalTranscode(t *testing.T) {
@ -61,3 +64,11 @@ func TestIntervalNormalize(t *testing.T) {
},
})
}
func TestIntervalLossyConversionToDuration(t *testing.T) {
interval := &pgtype.Interval{Months: 1, Days: 1, Status: pgtype.Present}
var d time.Duration
err := interval.AssignTo(&d)
require.NoError(t, err)
assert.EqualValues(t, int64(2678400000000000), d.Nanoseconds())
}