Allow converting intervals with months and days to duration

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

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

View File

@ -2,9 +2,12 @@ package pgtype_test
import ( import (
"testing" "testing"
"time"
"github.com/jackc/pgtype" "github.com/jackc/pgtype"
"github.com/jackc/pgtype/testutil" "github.com/jackc/pgtype/testutil"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
) )
func TestIntervalTranscode(t *testing.T) { 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())
}