Skip to content

Commit

Permalink
fixup! Adding new time funcs
Browse files Browse the repository at this point in the history
  • Loading branch information
hairyhenderson committed Sep 9, 2017
1 parent 31c86a2 commit d2723c5
Show file tree
Hide file tree
Showing 2 changed files with 114 additions and 0 deletions.
62 changes: 62 additions & 0 deletions funcs/time.go
Original file line number Diff line number Diff line change
@@ -1,7 +1,11 @@
package funcs

import (
"fmt"
"strconv"
"strings"
"sync"
gotime "time"

"github.com/hairyhenderson/gomplate/time"
)
Expand Down Expand Up @@ -34,3 +38,61 @@ func (f *TimeFuncs) ZoneName() string {
func (f *TimeFuncs) ZoneOffset() int {
return time.ZoneOffset()
}

// Parse -
func (f *TimeFuncs) Parse(layout, value string) (gotime.Time, error) {
return gotime.Parse(layout, value)
}

// Now -
func (f *TimeFuncs) Now() gotime.Time {
return gotime.Now()
}

// Unix - convert UNIX time (in seconds since the UNIX epoch) into a time.Time for further processing
// Takes a string or number (int or float)
func (f *TimeFuncs) Unix(in interface{}) (gotime.Time, error) {
sec, nsec, err := parseNum(in)
if err != nil {
return gotime.Time{}, err
}
return gotime.Unix(sec, nsec), nil
}

// convert a number input to a pair of int64s, representing the integer portion and the decimal remainder
// this can handle a string as well as any integer or float type
// precision is at the "nano" level (i.e. 1e+9)
func parseNum(in interface{}) (integral int64, fractional int64, err error) {
if s, ok := in.(string); ok {
ss := strings.Split(s, ".")
if len(ss) > 2 {
return 0, 0, fmt.Errorf("can not parse '%s' as a number - too many decimal points", s)
}
if len(ss) == 1 {
integral, err := strconv.ParseInt(s, 0, 64)
return integral, 0, err
}
integral, err := strconv.ParseInt(ss[0], 0, 64)
if err != nil {
return integral, 0, err
}
fractional, err = strconv.ParseInt(ss[1], 0, 64)
return integral, fractional, err
}
if s, ok := in.(fmt.Stringer); ok {
return parseNum(s.String())
}
if i, ok := in.(int); ok {
return int64(i), 0, nil
}
if u, ok := in.(uint64); ok {
return int64(u), 0, nil
}
if f, ok := in.(float64); ok {
return 0, 0, fmt.Errorf("can not parse floating point number (%f) - use a string instead", f)
}
if in == nil {
return 0, 0, nil
}
return 0, 0, nil
}
52 changes: 52 additions & 0 deletions funcs/time_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
package funcs

import (
"math"
"math/big"
"testing"

"github.com/stretchr/testify/assert"
)

func TestParseNum(t *testing.T) {
i, f, _ := parseNum("42")
assert.Equal(t, int64(42), i)
assert.Equal(t, int64(0), f)

i, f, _ = parseNum(42)
assert.Equal(t, int64(42), i)
assert.Equal(t, int64(0), f)

i, f, _ = parseNum(big.NewInt(42))
assert.Equal(t, int64(42), i)
assert.Equal(t, int64(0), f)

i, f, _ = parseNum(big.NewFloat(42.0))
assert.Equal(t, int64(42), i)
assert.Equal(t, int64(0), f)

i, f, _ = parseNum(uint64(math.MaxInt64))
assert.Equal(t, int64(uint64(math.MaxInt64)), i)
assert.Equal(t, int64(0), f)

i, f, _ = parseNum("9223372036854775807.9223372036854775807")
assert.Equal(t, int64(9223372036854775807), i)
assert.Equal(t, int64(9223372036854775807), f)

_, _, err := parseNum("bogus.9223372036854775807")
assert.Error(t, err)

_, _, err = parseNum("bogus")
assert.Error(t, err)

_, _, err = parseNum("1.2.3")
assert.Error(t, err)

_, _, err = parseNum(1.1)
assert.Error(t, err)

i, f, err = parseNum(nil)
assert.Zero(t, i)
assert.Zero(t, f)
assert.NoError(t, err)
}

0 comments on commit d2723c5

Please sign in to comment.