diff --git a/types/utils.go b/types/utils.go index fa2999a18..10ec85472 100644 --- a/types/utils.go +++ b/types/utils.go @@ -36,15 +36,22 @@ func MustSortJSON(toSortJSON []byte) []byte { return js } +// Slight modification of the RFC3339Nano but it right pads all zeros and drops the time zone info +const SortableTimeFormat = "2006-01-02T15:04:05.000000000" + // Formats a time.Time into a []byte that can be sorted func FormatTimeBytes(t time.Time) []byte { - return []byte(t.UTC().Round(0).Format("2006-01-02T15:04:05.000000000")) + return []byte(t.UTC().Round(0).Format(SortableTimeFormat)) } // Parses a []byte encoded using FormatTimeKey back into a time.Time func ParseTimeBytes(bz []byte) (time.Time, error) { str := string(bz) - return time.Parse("2006-01-02T15:04:05.000000000", str) + t, err := time.Parse(SortableTimeFormat, str) + if err != nil { + return t, err + } + return t.UTC().Round(0), nil } // DefaultChainID returns the chain ID from the genesis file if present. An diff --git a/types/utils_test.go b/types/utils_test.go index 05bc622e7..dbdd08c0a 100644 --- a/types/utils_test.go +++ b/types/utils_test.go @@ -2,6 +2,7 @@ package types import ( "testing" + "time" "github.com/stretchr/testify/require" ) @@ -43,3 +44,23 @@ func TestSortJSON(t *testing.T) { require.Equal(t, string(got), tc.want) } } + +func TestTimeFormatAndParse(t *testing.T) { + cases := []struct { + RFC3339NanoStr string + SDKSortableTimeStr string + Equal bool + }{ + {"2009-11-10T23:00:00Z", "2009-11-10T23:00:00.000000000", true}, + {"2011-01-10T23:10:05.758230235Z", "2011-01-10T23:10:05.758230235", true}, + } + for _, tc := range cases { + timeFromRFC, err := time.Parse(time.RFC3339Nano, tc.RFC3339NanoStr) + require.Nil(t, err) + timeFromSDKFormat, err := time.Parse(SortableTimeFormat, tc.SDKSortableTimeStr) + require.Nil(t, err) + + require.True(t, timeFromRFC.Equal(timeFromSDKFormat)) + require.Equal(t, timeFromRFC.Format(SortableTimeFormat), tc.SDKSortableTimeStr) + } +} diff --git a/x/stake/keeper/key.go b/x/stake/keeper/key.go index 6e6ff54ff..d5f2fc9d9 100644 --- a/x/stake/keeper/key.go +++ b/x/stake/keeper/key.go @@ -34,17 +34,6 @@ var ( const maxDigitsForAccount = 12 // ~220,000,000 atoms created at launch -// Formats a time.Time into a []byte that can be sorted -func FormatTimeKey(t time.Time) []byte { - return []byte(t.UTC().Round(0).Format("2006-01-02T15:04:05.000000000")) -} - -// Parses a []byte encoded using FormatTimeKey back into a time.Time -func ParseTimeKey(bz []byte) (time.Time, error) { - str := string(bz) - return time.Parse("2006-01-02T15:04:05.000000000", str) -} - // gets the key for the validator with address // VALUE: stake/types.Validator func GetValidatorKey(operatorAddr sdk.ValAddress) []byte {