Skip to content

Commit

Permalink
Merge pull request aws#260 from aws/timeFormat
Browse files Browse the repository at this point in the history
Correct millisecond unix-time behavior to mimic V1.
  • Loading branch information
skmcgrail authored Jan 15, 2021
2 parents c26c7c8 + aaabcce commit 655384d
Show file tree
Hide file tree
Showing 3 changed files with 55 additions and 12 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -118,7 +118,7 @@ private static GoDependency relativePackage(
private static final class Versions {
private static final String GO_STDLIB = "1.15";
private static final String GO_CMP = "v0.5.4";
private static final String SMITHY_GO = "v0.0.0-20210113172615-49588e1e8525";
private static final String SMITHY_GO = "v0.5.1-0.20210115041537-09631dea532e";
private static final String GO_JMESPATH = "v0.4.0";
}
}
15 changes: 11 additions & 4 deletions time/time.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package time

import (
"context"
"math/big"
"time"
)

Expand All @@ -13,6 +14,8 @@ const (
httpDateFormat = "Mon, 02 Jan 2006 15:04:05 GMT"
)

var millisecondFloat = big.NewFloat(1e3)

// FormatDateTime format value as a date-time (RFC3339 section 5.6)
//
// Example: 1985-04-12T23:20:50.52Z
Expand Down Expand Up @@ -43,16 +46,20 @@ func ParseHTTPDate(value string) (time.Time, error) {

// FormatEpochSeconds returns value as a Unix time in seconds with with decimal precision
//
// Example: 1515531081.1234
// Example: 1515531081.123
func FormatEpochSeconds(value time.Time) float64 {
return float64(value.UnixNano()) / float64(time.Second)
ms := value.UnixNano() / int64(time.Millisecond)
return float64(ms)/1e3
}

// ParseEpochSeconds returns value as a Unix time in seconds with with decimal precision
//
// Example: 1515531081.1234
// Example: 1515531081.123
func ParseEpochSeconds(value float64) time.Time {
return time.Unix(0, int64(value*float64(time.Second))).UTC()
f := big.NewFloat(value)
f = f.Mul(f, millisecondFloat)
i, _ := f.Int64()
return time.Unix(0, i*1e6).UTC()
}

// SleepWithContext will wait for the timer duration to expire, or the context
Expand Down
50 changes: 43 additions & 7 deletions time/time_test.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
package time

import (
"math"
"strconv"
"testing"
"time"
)
Expand Down Expand Up @@ -42,16 +44,50 @@ func TestHTTPDate(t *testing.T) {
}

func TestEpochSeconds(t *testing.T) {
refTime := time.Date(2018, 1, 9, 20, 51, 21, 123399936, time.UTC)

epochSeconds := FormatEpochSeconds(refTime)
if e, a := 1515531081.1234, epochSeconds; e != a {
t.Errorf("expected %v, got %v", e, a)
cases := []struct {
reference time.Time
expectedUnix float64
expectedTime time.Time
}{
{
reference: time.Date(2018, 1, 9, 20, 51, 21, 123399936, time.UTC),
expectedUnix: 1515531081.123,
expectedTime: time.Date(2018, 1, 9, 20, 51, 21, 1.23e8, time.UTC),
},
{
reference: time.Date(2018, 1, 9, 20, 51, 21, 1e8, time.UTC),
expectedUnix: 1515531081.1,
expectedTime: time.Date(2018, 1, 9, 20, 51, 21, 1e8, time.UTC),
},
{
reference: time.Date(2018, 1, 9, 20, 51, 21, 123567891, time.UTC),
expectedUnix: 1515531081.123,
expectedTime: time.Date(2018, 1, 9, 20, 51, 21, 1.23e8, time.UTC),
},
{
reference: time.Unix(0, math.MaxInt64).UTC(),
expectedUnix: 9223372036.854,
expectedTime: time.Date(2262, 04, 11, 23, 47, 16, 8.54e8, time.UTC),
},
}

parseTime := ParseEpochSeconds(epochSeconds)
for i, tt := range cases {
t.Run(strconv.Itoa(i), func(t *testing.T) {
epochSeconds := FormatEpochSeconds(tt.reference)
if e, a := tt.expectedUnix, epochSeconds; e != a {
t.Errorf("expected %v, got %v", e, a)
}

if e, a := refTime, parseTime; !e.Equal(a) {
parseTime := ParseEpochSeconds(epochSeconds)

if e, a := tt.expectedTime, parseTime; !e.Equal(a) {
t.Errorf("expected %v, got %v", e, a)
}
})
}

// Check an additional edge that higher precision values are truncated to milliseconds
if e, a := time.Date(2018, 1, 9, 20, 51, 21, 1.23e8, time.UTC), ParseEpochSeconds(1515531081.12356); !e.Equal(a) {
t.Errorf("expected %v, got %v", e, a)
}
}

0 comments on commit 655384d

Please sign in to comment.