Compare commits

...

6 Commits

Author SHA1 Message Date
289b9f47a2 v0.0.95 2023-03-28 16:29:16 +02:00
007c44df85 v0.0.94 2023-03-21 16:00:15 +01:00
a6252f0743 v0.0.93 2023-03-15 15:41:55 +01:00
86c01659d7 base58 2023-03-15 14:00:48 +01:00
62acddda5e v0.0.91 2023-03-11 14:38:19 +01:00
ee325f67fd v0.0.90 2023-03-09 14:51:53 +01:00
13 changed files with 429 additions and 55 deletions

View File

@@ -32,7 +32,13 @@ echo ""
git add --verbose . git add --verbose .
git commit -a -m "v${next_ver}" msg="v${next_ver}"
if [ $# -gt 0 ]; then
msg="$1"
fi
git commit -a -m "${msg}"
git tag "v${next_ver}" git tag "v${next_ver}"

View File

@@ -22,10 +22,10 @@ import (
// //
// sub-structs are recursively parsed (if they have an env tag) and the env-variable keys are delimited by the delim parameter // sub-structs are recursively parsed (if they have an env tag) and the env-variable keys are delimited by the delim parameter
// sub-structs with `env:""` are also parsed, but the delimited is skipped (they are handled as if they were one level higher) // sub-structs with `env:""` are also parsed, but the delimited is skipped (they are handled as if they were one level higher)
func ApplyEnvOverrides[T any](c *T, delim string) error { func ApplyEnvOverrides[T any](prefix string, c *T, delim string) error {
rval := reflect.ValueOf(c).Elem() rval := reflect.ValueOf(c).Elem()
return processEnvOverrides(rval, delim, "") return processEnvOverrides(rval, delim, prefix)
} }
func processEnvOverrides(rval reflect.Value, delim string, prefix string) error { func processEnvOverrides(rval reflect.Value, delim string, prefix string) error {

View File

@@ -265,6 +265,26 @@ func ArrMap[T1 any, T2 any](arr []T1, conv func(v T1) T2) []T2 {
return r return r
} }
func MapMap[TK comparable, TV any, TR any](inmap map[TK]TV, conv func(k TK, v TV) TR) []TR {
r := make([]TR, 0, len(inmap))
for k, v := range inmap {
r = append(r, conv(k, v))
}
return r
}
func MapMapErr[TK comparable, TV any, TR any](inmap map[TK]TV, conv func(k TK, v TV) (TR, error)) ([]TR, error) {
r := make([]TR, 0, len(inmap))
for k, v := range inmap {
elem, err := conv(k, v)
if err != nil {
return nil, err
}
r = append(r, elem)
}
return r, nil
}
func ArrMapExt[T1 any, T2 any](arr []T1, conv func(idx int, v T1) T2) []T2 { func ArrMapExt[T1 any, T2 any](arr []T1, conv func(idx int, v T1) T2) []T2 {
r := make([]T2, len(arr)) r := make([]T2, len(arr))
for i, v := range arr { for i, v := range arr {
@@ -295,6 +315,16 @@ func ArrFilterMap[T1 any, T2 any](arr []T1, filter func(v T1) bool, conv func(v
return r return r
} }
func ArrFilter[T any](arr []T, filter func(v T) bool) []T {
r := make([]T, 0, len(arr))
for _, v := range arr {
if filter(v) {
r = append(r, v)
}
}
return r
}
func ArrSum[T NumberConstraint](arr []T) T { func ArrSum[T NumberConstraint](arr []T) T {
var r T = 0 var r T = 0
for _, v := range arr { for _, v := range arr {

178
langext/base58.go Normal file
View File

@@ -0,0 +1,178 @@
package langext
import (
"bytes"
"errors"
"math/big"
)
// shamelessly stolen from https://github.com/btcsuite/
type B58Encoding struct {
bigRadix [11]*big.Int
bigRadix10 *big.Int
alphabet string
alphabetIdx0 byte
b58 [256]byte
}
var Base58DefaultEncoding = newBase58Encoding("123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz")
var Base58FlickrEncoding = newBase58Encoding("123456789abcdefghijkmnopqrstuvwxyzABCDEFGHJKLMNPQRSTUVWXYZ")
var Base58RippleEncoding = newBase58Encoding("rpshnaf39wBUDNEGHJKLM4PQRST7VWXYZ2bcdeCg65jkm8oFqi1tuvAxyz")
var Base58BitcoinEncoding = newBase58Encoding("123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz")
func newBase58Encoding(alphabet string) *B58Encoding {
bigRadix10 := big.NewInt(58 * 58 * 58 * 58 * 58 * 58 * 58 * 58 * 58 * 58)
enc := &B58Encoding{
alphabet: alphabet,
alphabetIdx0: '1',
bigRadix: [...]*big.Int{
big.NewInt(0),
big.NewInt(58),
big.NewInt(58 * 58),
big.NewInt(58 * 58 * 58),
big.NewInt(58 * 58 * 58 * 58),
big.NewInt(58 * 58 * 58 * 58 * 58),
big.NewInt(58 * 58 * 58 * 58 * 58 * 58),
big.NewInt(58 * 58 * 58 * 58 * 58 * 58 * 58),
big.NewInt(58 * 58 * 58 * 58 * 58 * 58 * 58 * 58),
big.NewInt(58 * 58 * 58 * 58 * 58 * 58 * 58 * 58 * 58),
bigRadix10,
},
bigRadix10: bigRadix10,
}
b58 := make([]byte, 0, 256)
for i := byte(0); i < 32; i++ {
for j := byte(0); j < 8; j++ {
b := i*8 + j
idx := bytes.IndexByte([]byte(alphabet), b)
if idx == -1 {
b58 = append(b58, 255)
} else {
b58 = append(b58, byte(idx))
}
}
}
enc.b58 = *((*[256]byte)(b58))
return enc
}
func (enc *B58Encoding) EncodeString(src string) (string, error) {
v, err := enc.Encode([]byte(src))
if err != nil {
return "", err
}
return string(v), nil
}
func (enc *B58Encoding) Encode(src []byte) ([]byte, error) {
x := new(big.Int)
x.SetBytes(src)
// maximum length of output is log58(2^(8*len(b))) == len(b) * 8 / log(58)
maxlen := int(float64(len(src))*1.365658237309761) + 1
answer := make([]byte, 0, maxlen)
mod := new(big.Int)
for x.Sign() > 0 {
// Calculating with big.Int is slow for each iteration.
// x, mod = x / 58, x % 58
//
// Instead we can try to do as much calculations on int64.
// x, mod = x / 58^10, x % 58^10
//
// Which will give us mod, which is 10 digit base58 number.
// We'll loop that 10 times to convert to the answer.
x.DivMod(x, enc.bigRadix10, mod)
if x.Sign() == 0 {
// When x = 0, we need to ensure we don't add any extra zeros.
m := mod.Int64()
for m > 0 {
answer = append(answer, enc.alphabet[m%58])
m /= 58
}
} else {
m := mod.Int64()
for i := 0; i < 10; i++ {
answer = append(answer, enc.alphabet[m%58])
m /= 58
}
}
}
// leading zero bytes
for _, i := range src {
if i != 0 {
break
}
answer = append(answer, enc.alphabetIdx0)
}
// reverse
alen := len(answer)
for i := 0; i < alen/2; i++ {
answer[i], answer[alen-1-i] = answer[alen-1-i], answer[i]
}
return answer, nil
}
func (enc *B58Encoding) DecodeString(src string) (string, error) {
v, err := enc.Decode([]byte(src))
if err != nil {
return "", err
}
return string(v), nil
}
func (enc *B58Encoding) Decode(src []byte) ([]byte, error) {
answer := big.NewInt(0)
scratch := new(big.Int)
for t := src; len(t) > 0; {
n := len(t)
if n > 10 {
n = 10
}
total := uint64(0)
for _, v := range t[:n] {
if v > 255 {
return []byte{}, errors.New("invalid char in input")
}
tmp := enc.b58[v]
if tmp == 255 {
return []byte{}, errors.New("invalid char in input")
}
total = total*58 + uint64(tmp)
}
answer.Mul(answer, enc.bigRadix[n])
scratch.SetUint64(total)
answer.Add(answer, scratch)
t = t[n:]
}
tmpval := answer.Bytes()
var numZeros int
for numZeros = 0; numZeros < len(src); numZeros++ {
if src[numZeros] != enc.alphabetIdx0 {
break
}
}
flen := numZeros + len(tmpval)
val := make([]byte, flen)
copy(val[numZeros:], tmpval)
return val, nil
}

67
langext/base58_test.go Normal file
View File

@@ -0,0 +1,67 @@
package langext
import (
"testing"
)
func _encStr(t *testing.T, enc *B58Encoding, v string) string {
v, err := enc.EncodeString(v)
if err != nil {
t.Error(err)
}
return v
}
func _decStr(t *testing.T, enc *B58Encoding, v string) string {
v, err := enc.DecodeString(v)
if err != nil {
t.Error(err)
}
return v
}
func TestBase58DefaultEncoding(t *testing.T) {
assertEqual(t, _encStr(t, Base58DefaultEncoding, "Hello"), "9Ajdvzr")
assertEqual(t, _encStr(t, Base58DefaultEncoding, "If debugging is the process of removing software bugs, then programming must be the process of putting them in."), "48638SMcJuah5okqPx4kCVf5d8QAdgbdNf28g7ReY13prUENNbMyssjq5GjsrJHF5zeZfqs4uJMUJHr7VbrU4XBUZ2Fw9DVtqtn9N1eXucEWSEZahXV6w4ysGSWqGdpeYTJf1MdDzTg8vfcQViifJjZX")
}
func TestBase58DefaultDecoding(t *testing.T) {
assertEqual(t, _decStr(t, Base58DefaultEncoding, "9Ajdvzr"), "Hello")
assertEqual(t, _decStr(t, Base58DefaultEncoding, "48638SMcJuah5okqPx4kCVf5d8QAdgbdNf28g7ReY13prUENNbMyssjq5GjsrJHF5zeZfqs4uJMUJHr7VbrU4XBUZ2Fw9DVtqtn9N1eXucEWSEZahXV6w4ysGSWqGdpeYTJf1MdDzTg8vfcQViifJjZX"), "If debugging is the process of removing software bugs, then programming must be the process of putting them in.")
}
func TestBase58RippleEncoding(t *testing.T) {
assertEqual(t, _encStr(t, Base58RippleEncoding, "Hello"), "9wjdvzi")
assertEqual(t, _encStr(t, Base58RippleEncoding, "If debugging is the process of removing software bugs, then programming must be the process of putting them in."), "h3as3SMcJu26nokqPxhkUVCnd3Qwdgbd4Cp3gfReYrsFi7N44bMy11jqnGj1iJHEnzeZCq1huJM7JHifVbi7hXB7ZpEA9DVtqt894reXucNWSNZ26XVaAhy1GSWqGdFeYTJCrMdDzTg3vCcQV55CJjZX")
}
func TestBase58RippleDecoding(t *testing.T) {
assertEqual(t, _decStr(t, Base58RippleEncoding, "9wjdvzi"), "Hello")
assertEqual(t, _decStr(t, Base58RippleEncoding, "h3as3SMcJu26nokqPxhkUVCnd3Qwdgbd4Cp3gfReYrsFi7N44bMy11jqnGj1iJHEnzeZCq1huJM7JHifVbi7hXB7ZpEA9DVtqt894reXucNWSNZ26XVaAhy1GSWqGdFeYTJCrMdDzTg3vCcQV55CJjZX"), "If debugging is the process of removing software bugs, then programming must be the process of putting them in.")
}
func TestBase58BitcoinEncoding(t *testing.T) {
assertEqual(t, _encStr(t, Base58BitcoinEncoding, "Hello"), "9Ajdvzr")
assertEqual(t, _encStr(t, Base58BitcoinEncoding, "If debugging is the process of removing software bugs, then programming must be the process of putting them in."), "48638SMcJuah5okqPx4kCVf5d8QAdgbdNf28g7ReY13prUENNbMyssjq5GjsrJHF5zeZfqs4uJMUJHr7VbrU4XBUZ2Fw9DVtqtn9N1eXucEWSEZahXV6w4ysGSWqGdpeYTJf1MdDzTg8vfcQViifJjZX")
}
func TestBase58BitcoinDecoding(t *testing.T) {
assertEqual(t, _decStr(t, Base58BitcoinEncoding, "9Ajdvzr"), "Hello")
assertEqual(t, _decStr(t, Base58BitcoinEncoding, "48638SMcJuah5okqPx4kCVf5d8QAdgbdNf28g7ReY13prUENNbMyssjq5GjsrJHF5zeZfqs4uJMUJHr7VbrU4XBUZ2Fw9DVtqtn9N1eXucEWSEZahXV6w4ysGSWqGdpeYTJf1MdDzTg8vfcQViifJjZX"), "If debugging is the process of removing software bugs, then programming must be the process of putting them in.")
}
func TestBase58FlickrEncoding(t *testing.T) {
assertEqual(t, _encStr(t, Base58FlickrEncoding, "Hello"), "9aJCVZR")
assertEqual(t, _encStr(t, Base58FlickrEncoding, "If debugging is the process of removing software bugs, then programming must be the process of putting them in."), "48638rmBiUzG5NKQoX4KcuE5C8paCFACnE28F7qDx13PRtennAmYSSJQ5gJSRihf5ZDyEQS4UimtihR7uARt4wbty2fW9duTQTM9n1DwUBevreyzGwu6W4YSgrvQgCPDxsiE1mCdZsF8VEBpuHHEiJyw")
}
func TestBase58FlickrDecoding(t *testing.T) {
assertEqual(t, _decStr(t, Base58FlickrEncoding, "9aJCVZR"), "Hello")
assertEqual(t, _decStr(t, Base58FlickrEncoding, "48638rmBiUzG5NKQoX4KcuE5C8paCFACnE28F7qDx13PRtennAmYSSJQ5gJSRihf5ZDyEQS4UimtihR7uARt4wbty2fW9duTQTM9n1DwUBevreyzGwu6W4YSgrvQgCPDxsiE1mCdZsF8VEBpuHHEiJyw"), "If debugging is the process of removing software bugs, then programming must be the process of putting them in.")
}
func assertEqual(t *testing.T, actual string, expected string) {
if actual != expected {
t.Errorf("values differ: Actual: '%v', Expected: '%v'", actual, expected)
}
}

View File

@@ -60,3 +60,12 @@ func CoalesceStringer(s fmt.Stringer, def string) string {
return s.String() return s.String()
} }
} }
func SafeCast[T any](v any, def T) T {
switch r := v.(type) {
case T:
return r
default:
return def
}
}

View File

@@ -3,24 +3,27 @@ package rfctime
import "time" import "time"
type RFCTime interface { type RFCTime interface {
AnyTime
Time() time.Time Time() time.Time
Serialize() string Serialize() string
UnmarshalJSON(bytes []byte) error After(u AnyTime) bool
Before(u AnyTime) bool
Equal(u AnyTime) bool
Sub(u AnyTime) time.Duration
}
type AnyTime interface {
MarshalJSON() ([]byte, error) MarshalJSON() ([]byte, error)
MarshalBinary() ([]byte, error) MarshalBinary() ([]byte, error)
UnmarshalBinary(data []byte) error
GobEncode() ([]byte, error) GobEncode() ([]byte, error)
GobDecode(data []byte) error
MarshalText() ([]byte, error) MarshalText() ([]byte, error)
UnmarshalText(data []byte) error
After(u RFCTime) bool
Before(u RFCTime) bool
Equal(u RFCTime) bool
IsZero() bool IsZero() bool
Date() (year int, month time.Month, day int) Date() (year int, month time.Month, day int)
Year() int Year() int
@@ -34,7 +37,6 @@ type RFCTime interface {
Second() int Second() int
Nanosecond() int Nanosecond() int
YearDay() int YearDay() int
Sub(u RFCTime) time.Duration
Unix() int64 Unix() int64
UnixMilli() int64 UnixMilli() int64
UnixMicro() int64 UnixMicro() int64
@@ -42,6 +44,8 @@ type RFCTime interface {
Format(layout string) string Format(layout string) string
GoString() string GoString() string
String() string String() string
Location() *time.Location
} }
type RFCDuration interface { type RFCDuration interface {
@@ -60,9 +64,9 @@ type RFCDuration interface {
MarshalText() ([]byte, error) MarshalText() ([]byte, error)
UnmarshalText(data []byte) error UnmarshalText(data []byte) error
After(u RFCTime) bool After(u AnyTime) bool
Before(u RFCTime) bool Before(u AnyTime) bool
Equal(u RFCTime) bool Equal(u AnyTime) bool
IsZero() bool IsZero() bool
Date() (year int, month time.Month, day int) Date() (year int, month time.Month, day int)
Year() int Year() int
@@ -76,7 +80,7 @@ type RFCDuration interface {
Second() int Second() int
Nanosecond() int Nanosecond() int
YearDay() int YearDay() int
Sub(u RFCTime) time.Duration Sub(u AnyTime) time.Duration
Unix() int64 Unix() int64
UnixMilli() int64 UnixMilli() int64
UnixMicro() int64 UnixMicro() int64
@@ -85,3 +89,13 @@ type RFCDuration interface {
GoString() string GoString() string
String() string String() string
} }
func tt(v AnyTime) time.Time {
if r, ok := v.(time.Time); ok {
return r
}
if r, ok := v.(RFCTime); ok {
return r.Time()
}
return time.Unix(0, v.UnixNano()).In(v.Location())
}

50
rfctime/interface_test.go Normal file
View File

@@ -0,0 +1,50 @@
package rfctime
import (
"testing"
"time"
)
func TestAnyTimeInterface(t *testing.T) {
var v AnyTime
v = NowRFC3339Nano()
assertEqual(t, v.String(), v.String())
v = NowRFC3339()
assertEqual(t, v.String(), v.String())
v = NowUnix()
assertEqual(t, v.String(), v.String())
v = NowUnixMilli()
assertEqual(t, v.String(), v.String())
v = NowUnixNano()
assertEqual(t, v.String(), v.String())
v = time.Now()
assertEqual(t, v.String(), v.String())
}
func TestRFCTimeInterface(t *testing.T) {
var v RFCTime
v = NowRFC3339Nano()
assertEqual(t, v.String(), v.String())
v = NowRFC3339()
assertEqual(t, v.String(), v.String())
v = NowUnix()
assertEqual(t, v.String(), v.String())
v = NowUnixMilli()
assertEqual(t, v.String(), v.String())
v = NowUnixNano()
assertEqual(t, v.String(), v.String())
}

View File

@@ -90,16 +90,16 @@ func (t RFC3339Time) FormatStr() string {
return time.RFC3339 return time.RFC3339
} }
func (t RFC3339Time) After(u RFCTime) bool { func (t RFC3339Time) After(u AnyTime) bool {
return t.Time().After(u.Time()) return t.Time().After(tt(u))
} }
func (t RFC3339Time) Before(u RFCTime) bool { func (t RFC3339Time) Before(u AnyTime) bool {
return t.Time().Before(u.Time()) return t.Time().Before(tt(u))
} }
func (t RFC3339Time) Equal(u RFCTime) bool { func (t RFC3339Time) Equal(u AnyTime) bool {
return t.Time().Equal(u.Time()) return t.Time().Equal(tt(u))
} }
func (t RFC3339Time) IsZero() bool { func (t RFC3339Time) IsZero() bool {
@@ -158,8 +158,8 @@ func (t RFC3339Time) Add(d time.Duration) RFC3339Time {
return RFC3339Time(t.Time().Add(d)) return RFC3339Time(t.Time().Add(d))
} }
func (t RFC3339Time) Sub(u RFCTime) time.Duration { func (t RFC3339Time) Sub(u AnyTime) time.Duration {
return t.Time().Sub(u.Time()) return t.Time().Sub(tt(u))
} }
func (t RFC3339Time) AddDate(years int, months int, days int) RFC3339Time { func (t RFC3339Time) AddDate(years int, months int, days int) RFC3339Time {
@@ -194,6 +194,10 @@ func (t RFC3339Time) String() string {
return t.Time().String() return t.Time().String()
} }
func (t RFC3339Time) Location() *time.Location {
return t.Time().Location()
}
func NewRFC3339(t time.Time) RFC3339Time { func NewRFC3339(t time.Time) RFC3339Time {
return RFC3339Time(t) return RFC3339Time(t)
} }

View File

@@ -90,16 +90,16 @@ func (t RFC3339NanoTime) FormatStr() string {
return time.RFC3339Nano return time.RFC3339Nano
} }
func (t RFC3339NanoTime) After(u RFCTime) bool { func (t RFC3339NanoTime) After(u AnyTime) bool {
return t.Time().After(u.Time()) return t.Time().After(tt(u))
} }
func (t RFC3339NanoTime) Before(u RFCTime) bool { func (t RFC3339NanoTime) Before(u AnyTime) bool {
return t.Time().Before(u.Time()) return t.Time().Before(tt(u))
} }
func (t RFC3339NanoTime) Equal(u RFCTime) bool { func (t RFC3339NanoTime) Equal(u AnyTime) bool {
return t.Time().Equal(u.Time()) return t.Time().Equal(tt(u))
} }
func (t RFC3339NanoTime) IsZero() bool { func (t RFC3339NanoTime) IsZero() bool {
@@ -158,8 +158,8 @@ func (t RFC3339NanoTime) Add(d time.Duration) RFC3339NanoTime {
return RFC3339NanoTime(t.Time().Add(d)) return RFC3339NanoTime(t.Time().Add(d))
} }
func (t RFC3339NanoTime) Sub(u RFCTime) time.Duration { func (t RFC3339NanoTime) Sub(u AnyTime) time.Duration {
return t.Time().Sub(u.Time()) return t.Time().Sub(tt(u))
} }
func (t RFC3339NanoTime) AddDate(years int, months int, days int) RFC3339NanoTime { func (t RFC3339NanoTime) AddDate(years int, months int, days int) RFC3339NanoTime {
@@ -194,6 +194,10 @@ func (t RFC3339NanoTime) String() string {
return t.Time().String() return t.Time().String()
} }
func (t RFC3339NanoTime) Location() *time.Location {
return t.Time().Location()
}
func NewRFC3339Nano(t time.Time) RFC3339NanoTime { func NewRFC3339Nano(t time.Time) RFC3339NanoTime {
return RFC3339NanoTime(t) return RFC3339NanoTime(t)
} }

View File

@@ -63,16 +63,16 @@ func (t UnixTime) Serialize() string {
return strconv.FormatInt(t.Time().Unix(), 10) return strconv.FormatInt(t.Time().Unix(), 10)
} }
func (t UnixTime) After(u RFCTime) bool { func (t UnixTime) After(u AnyTime) bool {
return t.Time().After(u.Time()) return t.Time().After(tt(u))
} }
func (t UnixTime) Before(u RFCTime) bool { func (t UnixTime) Before(u AnyTime) bool {
return t.Time().Before(u.Time()) return t.Time().Before(tt(u))
} }
func (t UnixTime) Equal(u RFCTime) bool { func (t UnixTime) Equal(u AnyTime) bool {
return t.Time().Equal(u.Time()) return t.Time().Equal(tt(u))
} }
func (t UnixTime) IsZero() bool { func (t UnixTime) IsZero() bool {
@@ -131,8 +131,8 @@ func (t UnixTime) Add(d time.Duration) UnixTime {
return UnixTime(t.Time().Add(d)) return UnixTime(t.Time().Add(d))
} }
func (t UnixTime) Sub(u RFCTime) time.Duration { func (t UnixTime) Sub(u AnyTime) time.Duration {
return t.Time().Sub(u.Time()) return t.Time().Sub(tt(u))
} }
func (t UnixTime) AddDate(years int, months int, days int) UnixTime { func (t UnixTime) AddDate(years int, months int, days int) UnixTime {
@@ -167,6 +167,10 @@ func (t UnixTime) String() string {
return t.Time().String() return t.Time().String()
} }
func (t UnixTime) Location() *time.Location {
return t.Time().Location()
}
func NewUnix(t time.Time) UnixTime { func NewUnix(t time.Time) UnixTime {
return UnixTime(t) return UnixTime(t)
} }

View File

@@ -63,16 +63,16 @@ func (t UnixMilliTime) Serialize() string {
return strconv.FormatInt(t.Time().UnixMilli(), 10) return strconv.FormatInt(t.Time().UnixMilli(), 10)
} }
func (t UnixMilliTime) After(u RFCTime) bool { func (t UnixMilliTime) After(u AnyTime) bool {
return t.Time().After(u.Time()) return t.Time().After(tt(u))
} }
func (t UnixMilliTime) Before(u RFCTime) bool { func (t UnixMilliTime) Before(u AnyTime) bool {
return t.Time().Before(u.Time()) return t.Time().Before(tt(u))
} }
func (t UnixMilliTime) Equal(u RFCTime) bool { func (t UnixMilliTime) Equal(u AnyTime) bool {
return t.Time().Equal(u.Time()) return t.Time().Equal(tt(u))
} }
func (t UnixMilliTime) IsZero() bool { func (t UnixMilliTime) IsZero() bool {
@@ -131,8 +131,8 @@ func (t UnixMilliTime) Add(d time.Duration) UnixMilliTime {
return UnixMilliTime(t.Time().Add(d)) return UnixMilliTime(t.Time().Add(d))
} }
func (t UnixMilliTime) Sub(u RFCTime) time.Duration { func (t UnixMilliTime) Sub(u AnyTime) time.Duration {
return t.Time().Sub(u.Time()) return t.Time().Sub(tt(u))
} }
func (t UnixMilliTime) AddDate(years int, months int, days int) UnixMilliTime { func (t UnixMilliTime) AddDate(years int, months int, days int) UnixMilliTime {
@@ -167,6 +167,10 @@ func (t UnixMilliTime) String() string {
return t.Time().String() return t.Time().String()
} }
func (t UnixMilliTime) Location() *time.Location {
return t.Time().Location()
}
func NewUnixMilli(t time.Time) UnixMilliTime { func NewUnixMilli(t time.Time) UnixMilliTime {
return UnixMilliTime(t) return UnixMilliTime(t)
} }

View File

@@ -63,16 +63,16 @@ func (t UnixNanoTime) Serialize() string {
return strconv.FormatInt(t.Time().UnixNano(), 10) return strconv.FormatInt(t.Time().UnixNano(), 10)
} }
func (t UnixNanoTime) After(u RFCTime) bool { func (t UnixNanoTime) After(u AnyTime) bool {
return t.Time().After(u.Time()) return t.Time().After(tt(u))
} }
func (t UnixNanoTime) Before(u RFCTime) bool { func (t UnixNanoTime) Before(u AnyTime) bool {
return t.Time().Before(u.Time()) return t.Time().Before(tt(u))
} }
func (t UnixNanoTime) Equal(u RFCTime) bool { func (t UnixNanoTime) Equal(u AnyTime) bool {
return t.Time().Equal(u.Time()) return t.Time().Equal(tt(u))
} }
func (t UnixNanoTime) IsZero() bool { func (t UnixNanoTime) IsZero() bool {
@@ -131,8 +131,8 @@ func (t UnixNanoTime) Add(d time.Duration) UnixNanoTime {
return UnixNanoTime(t.Time().Add(d)) return UnixNanoTime(t.Time().Add(d))
} }
func (t UnixNanoTime) Sub(u RFCTime) time.Duration { func (t UnixNanoTime) Sub(u AnyTime) time.Duration {
return t.Time().Sub(u.Time()) return t.Time().Sub(tt(u))
} }
func (t UnixNanoTime) AddDate(years int, months int, days int) UnixNanoTime { func (t UnixNanoTime) AddDate(years int, months int, days int) UnixNanoTime {
@@ -167,6 +167,10 @@ func (t UnixNanoTime) String() string {
return t.Time().String() return t.Time().String()
} }
func (t UnixNanoTime) Location() *time.Location {
return t.Time().Location()
}
func NewUnixNano(t time.Time) UnixNanoTime { func NewUnixNano(t time.Time) UnixNanoTime {
return UnixNanoTime(t) return UnixNanoTime(t)
} }