Add time support

This commit is contained in:
Unknwon
2015-01-01 20:33:52 +08:00
parent 70a46eeb84
commit 89772555bf
2 changed files with 98 additions and 10 deletions
+69 -9
View File
@@ -27,6 +27,7 @@ import (
"strconv"
"strings"
"sync"
"time"
)
const (
@@ -157,6 +158,16 @@ func (k *Key) Int64() (int64, error) {
return strconv.ParseInt(k.String(), 10, 64)
}
// TimeFormat parses with given format and returns time.Time type value.
func (k *Key) TimeFormat(format string) (time.Time, error) {
return time.Parse(format, k.String())
}
// Time parses with RFC3339 format and returns time.Time type value.
func (k *Key) Time() (time.Time, error) {
return k.TimeFormat(time.RFC3339)
}
// MustString returns default value if key value is empty.
func (k *Key) MustString(defaultVal string) string {
val := k.String()
@@ -179,31 +190,47 @@ func (k *Key) MustBool(defaultVal ...bool) bool {
// MustFloat64 always returns value without error,
// it returns 0.0 if error occurs.
func (k *Key) MustFloat64(defaultVal ...float64) float64 {
value, err := k.Float64()
val, err := k.Float64()
if len(defaultVal) > 0 && err != nil {
return defaultVal[0]
}
return value
return val
}
// MustInt always returns value without error,
// it returns 0 if error occurs.
func (k *Key) MustInt(defaultVal ...int) int {
value, err := k.Int()
val, err := k.Int()
if len(defaultVal) > 0 && err != nil {
return defaultVal[0]
}
return value
return val
}
// MustInt64 always returns value without error,
// it returns 0 if error occurs.
func (k *Key) MustInt64(defaultVal ...int64) int64 {
value, err := k.Int64()
val, err := k.Int64()
if len(defaultVal) > 0 && err != nil {
return defaultVal[0]
}
return value
return val
}
// MustTimeFormat always parses with given format and returns value without error,
// it returns zero value if error occurs.
func (k *Key) MustTimeFormat(format string, defaultVal ...time.Time) time.Time {
val, err := k.TimeFormat(format)
if len(defaultVal) > 0 && err != nil {
return defaultVal[0]
}
return val
}
// MustTime always parses with RFC3339 format and returns value without error,
// it returns zero value if error occurs.
func (k *Key) MustTime(defaultVal ...time.Time) time.Time {
return k.MustTimeFormat(time.RFC3339, defaultVal...)
}
// In always returns value without error,
@@ -218,7 +245,7 @@ func (k *Key) In(defaultVal string, candidates []string) string {
return defaultVal
}
// In always returns value without error,
// InFloat64 always returns value without error,
// it returns default value if error occurs or doesn't fit into candidates.
func (k *Key) InFloat64(defaultVal float64, candidates []float64) float64 {
val := k.MustFloat64()
@@ -230,7 +257,7 @@ func (k *Key) InFloat64(defaultVal float64, candidates []float64) float64 {
return defaultVal
}
// In always returns value without error,
// InInt always returns value without error,
// it returns default value if error occurs or doesn't fit into candidates.
func (k *Key) InInt(defaultVal int, candidates []int) int {
val := k.MustInt()
@@ -242,7 +269,7 @@ func (k *Key) InInt(defaultVal int, candidates []int) int {
return defaultVal
}
// In always returns value without error,
// InInt64 always returns value without error,
// it returns default value if error occurs or doesn't fit into candidates.
func (k *Key) InInt64(defaultVal int64, candidates []int64) int64 {
val := k.MustInt64()
@@ -254,6 +281,24 @@ func (k *Key) InInt64(defaultVal int64, candidates []int64) int64 {
return defaultVal
}
// InTimeFormat always parses with given format and returns value without error,
// it returns default value if error occurs or doesn't fit into candidates.
func (k *Key) InTimeFormat(format string, defaultVal time.Time, candidates []time.Time) time.Time {
val := k.MustTimeFormat(format)
for _, cand := range candidates {
if val == cand {
return val
}
}
return defaultVal
}
// InTime always parses with RFC3339 format and returns value without error,
// it returns default value if error occurs or doesn't fit into candidates.
func (k *Key) InTime(defaultVal time.Time, candidates []time.Time) time.Time {
return k.InTimeFormat(time.RFC3339, defaultVal, candidates)
}
// Strings returns list of string devide by given delimiter.
func (k *Key) Strings(delim string) []string {
str := k.String()
@@ -298,6 +343,21 @@ func (k *Key) Int64s(delim string) []int64 {
return vals
}
// TimesFormat parses with given format and returns list of time.Time devide by given delimiter.
func (k *Key) TimesFormat(format, delim string) []time.Time {
strs := k.Strings(delim)
vals := make([]time.Time, len(strs))
for i := range strs {
vals[i], _ = time.Parse(format, strs[i])
}
return vals
}
// Times parses with RFC3339 format and returns list of time.Time devide by given delimiter.
func (k *Key) Times(delim string) []time.Time {
return k.TimesFormat(time.RFC3339, delim)
}
// SetValue changes key value.
func (k *Key) SetValue(v string) {
k.value = v
+29 -1
View File
@@ -18,6 +18,7 @@ import (
"fmt"
"strings"
"testing"
"time"
. "github.com/smartystreets/goconvey/convey"
)
@@ -57,11 +58,13 @@ STRING = str
BOOL = true
FLOAT64 = 1.25
INT = 10
TIME = 2015-01-01T20:17:05Z
[array]
STRINGS = en, zh, de
FLOAT64S = 1.1, 2.2, 3.3
INTS = 1, 2, 3
TIMES = 2015-01-01T20:17:05Z,2015-01-01T20:17:05Z,2015-01-01T20:17:05Z
[note]
@@ -206,12 +209,19 @@ func Test_Values(t *testing.T) {
So(err, ShouldBeNil)
So(v4, ShouldEqual, 10)
t, err := time.Parse(time.RFC3339, "2015-01-01T20:17:05Z")
So(err, ShouldBeNil)
v5, err := sec.Key("TIME").Time()
So(err, ShouldBeNil)
So(v5.String(), ShouldEqual, t.String())
Convey("Must get values with type", func() {
So(sec.Key("STRING").MustString("404"), ShouldEqual, "str")
So(sec.Key("BOOL").MustBool(), ShouldBeTrue)
So(sec.Key("FLOAT64").MustFloat64(), ShouldEqual, 1.25)
So(sec.Key("INT").MustInt(), ShouldEqual, 10)
So(sec.Key("INT").MustInt64(), ShouldEqual, 10)
So(sec.Key("TIME").MustTime().String(), ShouldEqual, t.String())
Convey("Must get values with default value", func() {
So(sec.Key("STRING_404").MustString("404"), ShouldEqual, "404")
@@ -219,6 +229,10 @@ func Test_Values(t *testing.T) {
So(sec.Key("FLOAT64_404").MustFloat64(2.5), ShouldEqual, 2.5)
So(sec.Key("INT_404").MustInt(15), ShouldEqual, 15)
So(sec.Key("INT_404").MustInt64(15), ShouldEqual, 15)
t, err := time.Parse(time.RFC3339, "2014-01-01T20:17:05Z")
So(err, ShouldBeNil)
So(sec.Key("TIME_404").MustTime(t).String(), ShouldEqual, t.String())
})
})
})
@@ -230,11 +244,18 @@ func Test_Values(t *testing.T) {
So(sec.Key("INT").InInt(0, []int{10, 20, 30}), ShouldEqual, 10)
So(sec.Key("INT").InInt64(0, []int64{10, 20, 30}), ShouldEqual, 10)
zt, err := time.Parse(time.RFC3339, "0001-01-01T01:00:00Z")
So(err, ShouldBeNil)
t, err := time.Parse(time.RFC3339, "2015-01-01T20:17:05Z")
So(err, ShouldBeNil)
So(sec.Key("TIME").InTime(zt, []time.Time{t, time.Now(), time.Now().Add(1 * time.Second)}).String(), ShouldEqual, t.String())
Convey("Get value with candidates and default value", func() {
So(sec.Key("STRING_404").In("str", []string{"str", "arr", "types"}), ShouldEqual, "str")
So(sec.Key("FLOAT64_404").InFloat64(1.25, []float64{1.25, 2.5, 3.75}), ShouldEqual, 1.25)
So(sec.Key("INT_404").InInt(10, []int{10, 20, 30}), ShouldEqual, 10)
So(sec.Key("INT64_404").InInt64(10, []int64{10, 20, 30}), ShouldEqual, 10)
So(sec.Key("TIME_404").InTime(t, []time.Time{time.Now(), time.Now(), time.Now().Add(1 * time.Second)}).String(), ShouldEqual, t.String())
})
})
@@ -257,6 +278,13 @@ func Test_Values(t *testing.T) {
for i, v := range []int64{1, 2, 3} {
So(vals3[i], ShouldEqual, v)
}
t, err := time.Parse(time.RFC3339, "2015-01-01T20:17:05Z")
So(err, ShouldBeNil)
vals4 := sec.Key("TIMES").Times(",")
for i, v := range []time.Time{t, t, t} {
So(vals4[i].String(), ShouldEqual, v.String())
}
})
Convey("Get key hash", func() {
@@ -270,7 +298,7 @@ func Test_Values(t *testing.T) {
})
Convey("Get key strings", func() {
So(strings.Join(cfg.Section("types").KeyStrings(), ","), ShouldEqual, "STRING,BOOL,FLOAT64,INT")
So(strings.Join(cfg.Section("types").KeyStrings(), ","), ShouldEqual, "STRING,BOOL,FLOAT64,INT,TIME")
})
Convey("Delete a key", func() {