diff --git a/pkg/stdlib/datetime/date.go b/pkg/stdlib/datetime/date.go index e8def864..368b38e5 100644 --- a/pkg/stdlib/datetime/date.go +++ b/pkg/stdlib/datetime/date.go @@ -9,23 +9,32 @@ import ( "github.com/MontFerret/ferret/pkg/runtime/values/types" ) -// DATE converts RFC3339 date time string to DateTime object. -// @param {String} time - String in RFC3339 format. +// DATE parses a formatted string and returns DateTime object it represents. +// @param {String} time - String representation of DateTime. +// @param {String} [layout = "2006-01-02T15:04:05Z07:00"] - String layout. // @return {DateTime} - New DateTime object derived from timeString. func Date(_ context.Context, args ...core.Value) (core.Value, error) { - err := core.ValidateArgs(args, 1, 1) - if err != nil { + if err := core.ValidateArgs(args, 1, 2); err != nil { return values.None, err } - err = core.ValidateType(args[0], types.String) - if err != nil { + if err := core.ValidateType(args[0], types.String); err != nil { return values.None, err } - timeStrings := args[0].(values.String) + str := args[0].(values.String) + layout := values.DefaultTimeLayout + + if len(args) > 1 { + if err := core.ValidateType(args[1], types.String); err != nil { + return values.None, err + } + + layout = values.ToString(args[1]).String() + } + + t, err := time.Parse(layout, str.String()) - t, err := time.Parse(values.DefaultTimeLayout, timeStrings.String()) if err != nil { return values.None, err } diff --git a/pkg/stdlib/datetime/date_test.go b/pkg/stdlib/datetime/date_test.go index ab4298e3..fd88c61a 100644 --- a/pkg/stdlib/datetime/date_test.go +++ b/pkg/stdlib/datetime/date_test.go @@ -2,6 +2,7 @@ package datetime_test import ( "testing" + "time" "github.com/MontFerret/ferret/pkg/runtime/core" "github.com/MontFerret/ferret/pkg/runtime/values" @@ -10,29 +11,32 @@ import ( ) func TestDate(t *testing.T) { + now := time.Now() + tcs := []*testCase{ - &testCase{ - Name: "When more than 1 arguments", + { + Name: "When more than 2 arguments", Expected: values.None, Args: []core.Value{ - values.NewString("string"), - values.NewInt(0), + values.NewString(time.Now().Format(time.RFC3339)), + values.NewString(time.RFC3339), + values.NewString("foo"), }, ShouldErr: true, }, - &testCase{ + { Name: "When 0 arguments", Expected: values.None, Args: []core.Value{}, ShouldErr: true, }, - &testCase{ - Name: "When argument isn't DateTime", + { + Name: "When first argument isn't string", Expected: values.None, Args: []core.Value{values.NewInt(0)}, ShouldErr: true, }, - &testCase{ + { Name: "When incorrect timeStrings", Expected: values.None, Args: []core.Value{ @@ -40,13 +44,31 @@ func TestDate(t *testing.T) { }, ShouldErr: true, }, - &testCase{ - Name: "When correct timeString in RFC3339 format", + { + Name: "When string is in default format", Expected: mustDefaultLayoutDt("1999-02-07T15:04:05Z"), Args: []core.Value{ values.NewString("1999-02-07T15:04:05Z"), }, }, + { + Name: "When second argument isn't string", + Expected: values.None, + Args: []core.Value{ + values.NewString("1999-02-07T15:04:05Z"), + values.NewInt(1), + }, + ShouldErr: true, + }, + { + Name: "When string is in custom format", + Expected: mustLayoutDt(time.RFC822, now.Format(time.RFC822)), + Args: []core.Value{ + values.NewString(now.Format(time.RFC822)), + values.NewString(time.RFC822), + }, + ShouldErr: false, + }, } for _, tc := range tcs { diff --git a/pkg/stdlib/datetime/format.go b/pkg/stdlib/datetime/format.go index 68e4f76e..9ed21bc5 100644 --- a/pkg/stdlib/datetime/format.go +++ b/pkg/stdlib/datetime/format.go @@ -10,6 +10,7 @@ import ( // DATE_FORMAT format date according to the given format string. // @param {DateTime} date - Source DateTime object. +// @param {String} format - String format. // @return {String} - Formatted date. func DateFormat(_ context.Context, args ...core.Value) (core.Value, error) { err := core.ValidateArgs(args, 2, 2)