Skip to content

Commit

Permalink
Merge pull request #134 from ClickHouse/fix/handle-zero-time
Browse files Browse the repository at this point in the history
fix(proto): handle zero time
  • Loading branch information
ernado authored Jun 19, 2022
2 parents 29506bc + 5ae805b commit ab2badd
Show file tree
Hide file tree
Showing 4 changed files with 36 additions and 9 deletions.
6 changes: 6 additions & 0 deletions proto/datetime.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,17 @@ type DateTime int32

// ToDateTime converts time.Time to DateTime.
func ToDateTime(t time.Time) DateTime {
if t.IsZero() {
return 0
}
return DateTime(t.Unix())
}

// Time returns DateTime as time.Time.
func (d DateTime) Time() time.Time {
if d == 0 {
return time.Time{}
}
// https://clickhouse.com/docs/en/sql-reference/data-types/datetime/#usage-remarks
// ClickHouse stores UTC timestamps that are timezone-agnostic.
return time.Unix(int64(d), 0)
Expand Down
6 changes: 6 additions & 0 deletions proto/datetime64.go
Original file line number Diff line number Diff line change
Expand Up @@ -50,11 +50,17 @@ type DateTime64 int64

// ToDateTime64 converts time.Time to DateTime64.
func ToDateTime64(t time.Time, p Precision) DateTime64 {
if t.IsZero() {
return 0
}
return DateTime64(t.UnixNano() / p.Scale())
}

// Time returns DateTime64 as time.Time.
func (d DateTime64) Time(p Precision) time.Time {
if d == 0 {
return time.Time{}
}
nsec := int64(d) * p.Scale()
return time.Unix(nsec/1e9, nsec%1e9)
}
Expand Down
20 changes: 14 additions & 6 deletions proto/datetime64_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,18 +8,26 @@ import (
)

func TestDateTime64_Time(t *testing.T) {
v := time.Unix(1546290000, 0).UTC()
for _, p := range []Precision{
PrecisionSecond,
1,
PrecisionMilli,
PrecisionMicro,
PrecisionNano,
8,
} {
d := ToDateTime64(v, p)
vt := d.Time(p)
assert.Equal(t, ToDateTime64(v, p), d)
assert.Equal(t, v.Unix(), vt.Unix())
assert.True(t, p.Valid())
t.Run(p.Duration().String(), func(t *testing.T) {
for _, v := range []time.Time{
{}, // zero time
time.Unix(1546290000, 0).UTC(),
} {
d := ToDateTime64(v, p)
vt := d.Time(p)
assert.Equal(t, ToDateTime64(v, p), d)
assert.Equal(t, v.Unix(), vt.Unix())
assert.True(t, p.Valid())
}
})
}
t.Run("Duration", func(t *testing.T) {
assert.Equal(t, time.Second, PrecisionSecond.Duration(), "sec")
Expand Down
13 changes: 10 additions & 3 deletions proto/datetime_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,14 @@ import (
)

func TestDateTime_Time(t *testing.T) {
v := time.Unix(1546290000, 0).UTC()
d := ToDateTime(v)
assert.Equal(t, int32(1546290000), int32(d))
t.Run("Ok", func(t *testing.T) {
v := time.Unix(1546290000, 0).UTC()
d := ToDateTime(v)
assert.Equal(t, int32(1546290000), int32(d))
})
t.Run("Zero", func(t *testing.T) {
v := time.Time{}
d := ToDateTime(v)
assert.Equal(t, int32(0), int32(d))
})
}

0 comments on commit ab2badd

Please sign in to comment.