Skip to content

Commit

Permalink
GH-36935: [Go] Fix Timestamp to Time dates (#36964)
Browse files Browse the repository at this point in the history
### Rationale for this change
The previous solution converted everything to nanoseconds first but you end up with overflowing `int64` potentially. Since we've bumped the minimum version of the library to using go1.17+ we can use the newer `UnixMicro` and `UnixMilli` functions to make this easy.

### Are these changes tested?
Yes, unit test is added.

* Closes: #36935

Authored-by: Matt Topol <zotthewizard@gmail.com>
Signed-off-by: Matt Topol <zotthewizard@gmail.com>
  • Loading branch information
zeroshade committed Aug 1, 2023
1 parent 5bb53c7 commit 0fb744c
Show file tree
Hide file tree
Showing 2 changed files with 17 additions and 2 deletions.
12 changes: 10 additions & 2 deletions go/arrow/datatype_fixedwidth.go
Original file line number Diff line number Diff line change
Expand Up @@ -192,10 +192,16 @@ func TimestampFromString(val string, unit TimeUnit) (Timestamp, error) {
}

func (t Timestamp) ToTime(unit TimeUnit) time.Time {
if unit == Second {
switch unit {
case Second:
return time.Unix(int64(t), 0).UTC()
case Millisecond:
return time.UnixMilli(int64(t)).UTC()
case Microsecond:
return time.UnixMicro(int64(t)).UTC()
default:
return time.Unix(0, int64(t)).UTC()
}
return time.Unix(0, int64(t)*int64(unit.Multiplier())).UTC()
}

// TimestampFromTime allows converting time.Time to Timestamp
Expand Down Expand Up @@ -327,6 +333,8 @@ const (

var TimeUnitValues = []TimeUnit{Second, Millisecond, Microsecond, Nanosecond}

// Multiplier returns a time.Duration value to multiply by in order to
// convert the value into nanoseconds
func (u TimeUnit) Multiplier() time.Duration {
return [...]time.Duration{time.Second, time.Millisecond, time.Microsecond, time.Nanosecond}[uint(u)&3]
}
Expand Down
7 changes: 7 additions & 0 deletions go/arrow/datatype_fixedwidth_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -159,6 +159,13 @@ func TestTimestampType(t *testing.T) {
}
}

func TestTimestampToTime(t *testing.T) {
ts := arrow.Timestamp(11865225600000)
tm := ts.ToTime(arrow.Millisecond)

assert.Equal(t, "2345-12-30 00:00:00", tm.Format("2006-01-02 15:04:05.999"))
}

func TestTime32Type(t *testing.T) {
for _, tc := range []struct {
unit arrow.TimeUnit
Expand Down

0 comments on commit 0fb744c

Please sign in to comment.