-
-
Notifications
You must be signed in to change notification settings - Fork 73
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
3 changed files
with
176 additions
and
10 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,51 @@ | ||
package fasttime | ||
|
||
import ( | ||
"errors" | ||
"strconv" | ||
"strings" | ||
"time" | ||
) | ||
|
||
type Time time.Time | ||
|
||
func (t *Time) UnmarshalJSON(data []byte) error { | ||
ts, err := TS2int(strings.Trim(string(data), `"`)) | ||
if err != nil { | ||
return err | ||
} | ||
*t = Time(Int2Time(ts)) | ||
return nil | ||
} | ||
|
||
func (t Time) MarshalJSON() ([]byte, error) { | ||
ts := time.Time(t).UnixMicro() | ||
return []byte(`"` + Int2TS(ts) + `"`), nil | ||
} | ||
|
||
// TS2int converts a slack timestamp to an int64 by stripping the dot and | ||
// converting the string to an int64. It is useful for fast comparison. | ||
func TS2int(ts string) (int64, error) { | ||
before, after, found := strings.Cut(ts, ".") | ||
if !found { | ||
return 0, errors.New("not a slack timestamp") | ||
} | ||
return strconv.ParseInt(before+after, 10, 64) | ||
} | ||
|
||
// Int2TS converts an int64 to a slack timestamp by inserting a dot in the | ||
// right place. | ||
func Int2TS(ts int64) string { | ||
s := strconv.FormatInt(ts, 10) | ||
if len(s) < 7 { | ||
return "" | ||
} | ||
lo := s[len(s)-6:] | ||
hi := s[:len(s)-6] | ||
return hi + "." + lo | ||
} | ||
|
||
// Int2Time converts an int64 to a time.Time. | ||
func Int2Time(ts int64) time.Time { | ||
return time.UnixMicro(ts) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,114 @@ | ||
package fasttime | ||
|
||
import ( | ||
"reflect" | ||
"testing" | ||
"time" | ||
) | ||
|
||
func TestTs2int(t *testing.T) { | ||
type args struct { | ||
ts string | ||
} | ||
tests := []struct { | ||
name string | ||
args args | ||
want int64 | ||
wantErr bool | ||
}{ | ||
{ | ||
"valid ts", | ||
args{"1638494510.037400"}, | ||
1638494510037400, | ||
false, | ||
}, | ||
{ | ||
"invalid ts", | ||
args{"x"}, | ||
0, | ||
true, | ||
}, | ||
{ | ||
"real ts", | ||
args{"1674255434.388009"}, | ||
1674255434388009, | ||
false, | ||
}, | ||
{ | ||
"no dot", | ||
args{"1674255434"}, | ||
0, | ||
true, | ||
}, | ||
} | ||
for _, tt := range tests { | ||
t.Run(tt.name, func(t *testing.T) { | ||
got, err := TS2int(tt.args.ts) | ||
if (err != nil) != tt.wantErr { | ||
t.Errorf("TS2Int64() error = %v, wantErr %v", err, tt.wantErr) | ||
return | ||
} | ||
if got != tt.want { | ||
t.Errorf("TS2Int64() = %v, want %v", got, tt.want) | ||
} | ||
}) | ||
} | ||
} | ||
|
||
func TestInt2ts(t *testing.T) { | ||
type args struct { | ||
ts int64 | ||
} | ||
tests := []struct { | ||
name string | ||
args args | ||
want string | ||
}{ | ||
{ | ||
"valid ts", | ||
args{1638494510037400}, | ||
"1638494510.037400", | ||
}, | ||
{ | ||
"real ts", | ||
args{1674255434388009}, | ||
"1674255434.388009", | ||
}, | ||
{ | ||
"zero", | ||
args{0}, | ||
"", | ||
}, | ||
} | ||
for _, tt := range tests { | ||
t.Run(tt.name, func(t *testing.T) { | ||
if got := Int2TS(tt.args.ts); got != tt.want { | ||
t.Errorf("Int642TS() = %v, want %v", got, tt.want) | ||
} | ||
}) | ||
} | ||
} | ||
|
||
func TestInt2Time(t *testing.T) { | ||
type args struct { | ||
ts int64 | ||
} | ||
tests := []struct { | ||
name string | ||
args args | ||
want time.Time | ||
}{ | ||
{ | ||
"valid ts", | ||
args{1645054781942979}, | ||
time.Unix(1645054781, 942979000), | ||
}, | ||
} | ||
for _, tt := range tests { | ||
t.Run(tt.name, func(t *testing.T) { | ||
if got := Int2Time(tt.args.ts); !reflect.DeepEqual(got, tt.want) { | ||
t.Errorf("Int2Time() = %v, want %v", got, tt.want) | ||
} | ||
}) | ||
} | ||
} |