Skip to content

Commit

Permalink
Extended times lib functionality
Browse files Browse the repository at this point in the history
  • Loading branch information
vereecw committed Apr 13, 2022
1 parent 0afdfde commit 4bb560b
Show file tree
Hide file tree
Showing 3 changed files with 163 additions and 0 deletions.
4 changes: 4 additions & 0 deletions docs/stdlib-times.md
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,7 @@ times := import("times")
2006" would be interpreted if it were the value; it serves as an example of
the input format. The same interpretation will then be made to the input
string.
- `parseInLocation(format string, s string, loc string)`: parseInLocation is like parse but parse interprets a time as UTC; parseInLocation interprets the time as in the given location.
- `unix(sec int, nsec int) => time`: returns the local Time corresponding to
the given Unix time, sec seconds and nsec nanoseconds since January 1,
1970 UTC.
Expand All @@ -88,6 +89,7 @@ times := import("times")
- `time_month(t time) => int`: returns the month of the year specified by t.
- `time_day(t time) => int`: returns the day of the month specified by t.
- `time_weekday(t time) => int`: returns the day of the week specified by t.
- `time_yearday(t time) => int`: returns the day of the year specified by t, in the range [1,365] for non-leap years, and [1,366] in leap years.
- `time_hour(t time) => int`: returns the hour within the day specified by t,
in the range [0, 23].
- `time_minute(t time) => int`: returns the minute offset within the hour
Expand All @@ -114,6 +116,8 @@ times := import("times")
t.
- `time_string(t time) => string`: returns the time formatted using the format
string "2006-01-02 15:04:05.999999999 -0700 MST".
- `time_in(t time, loc string)`: returns a copy of t representing the same time instant, but with the copy's location information set to loc for display purposes.
- `is_dst(t time)`: reports whether the time in the configured location is in Daylight Savings Time.
- `is_zero(t time) => bool`: reports whether t represents the zero time
instant, January 1, year 1, 00:00:00 UTC.
- `to_local(t time) => time`: returns t with the location set to local time.
Expand Down
152 changes: 152 additions & 0 deletions stdlib/times.go
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,10 @@ var timesModule = map[string]tengo.Object{
Name: "parse",
Value: timesParse,
}, // parse(format, str) => time
"parseInLocation": &tengo.UserFunction{
Name: "parseInLocation",
Value: timesParseInLocation,
}, // parseInLocation(format, str, location) => time
"unix": &tengo.UserFunction{
Name: "unix",
Value: timesUnix,
Expand Down Expand Up @@ -132,6 +136,10 @@ var timesModule = map[string]tengo.Object{
Name: "time_weekday",
Value: timesTimeWeekday,
}, // time_weekday(time) => int
"time_yearday": &tengo.UserFunction{
Name: "time_yearday",
Value: timesTimeYearday,
}, // time_yearday(time) => int
"time_hour": &tengo.UserFunction{
Name: "time_hour",
Value: timesTimeHour,
Expand Down Expand Up @@ -168,6 +176,14 @@ var timesModule = map[string]tengo.Object{
Name: "time_string",
Value: timesTimeString,
}, // time_string(time) => string
"time_in": &tengo.UserFunction{
Name: "time_in",
Value: timesTimeIn,
}, // in(time, location) => time
"is_dst": &tengo.UserFunction{
Name: "is_dst",
Value: timesIsDST,
}, // is_dst(time) => bool
"is_zero": &tengo.UserFunction{
Name: "is_zero",
Value: timesIsZero,
Expand Down Expand Up @@ -555,6 +571,59 @@ func timesParse(args ...tengo.Object) (ret tengo.Object, err error) {
return
}

func timesParseInLocation(args ...tengo.Object) (ret tengo.Object, err error) {
if len(args) != 3 {
err = tengo.ErrWrongNumArguments
return
}

s1, ok := tengo.ToString(args[0])
if !ok {
err = tengo.ErrInvalidArgumentType{
Name: "first",
Expected: "string(compatible)",
Found: args[0].TypeName(),
}
return
}

s2, ok := tengo.ToString(args[1])
if !ok {
err = tengo.ErrInvalidArgumentType{
Name: "second",
Expected: "string(compatible)",
Found: args[1].TypeName(),
}
return
}

s3, ok := tengo.ToString(args[2])
if !ok {
err = tengo.ErrInvalidArgumentType{
Name: "third",
Expected: "string(compatible)",
Found: args[1].TypeName(),
}
return
}

location, err := time.LoadLocation(s3)
if err != nil {
ret = wrapError(err)
return
}

parsed, err := time.ParseInLocation(s1, s2, location)
if err != nil {
ret = wrapError(err)
return
}

ret = &tengo.Time{Value: parsed}

return
}

func timesUnix(args ...tengo.Object) (ret tengo.Object, err error) {
if len(args) != 2 {
err = tengo.ErrWrongNumArguments
Expand Down Expand Up @@ -853,6 +922,27 @@ func timesTimeWeekday(args ...tengo.Object) (ret tengo.Object, err error) {
return
}

func timesTimeYearday(args ...tengo.Object) (ret tengo.Object, err error) {
if len(args) != 1 {
err = tengo.ErrWrongNumArguments
return
}

t1, ok := tengo.ToTime(args[0])
if !ok {
err = tengo.ErrInvalidArgumentType{
Name: "first",
Expected: "time(compatible)",
Found: args[0].TypeName(),
}
return
}

ret = &tengo.Int{Value: int64(t1.YearDay())}

return
}

func timesTimeHour(args ...tengo.Object) (ret tengo.Object, err error) {
if len(args) != 1 {
err = tengo.ErrWrongNumArguments
Expand Down Expand Up @@ -1022,6 +1112,68 @@ func timesTimeFormat(args ...tengo.Object) (ret tengo.Object, err error) {
return
}

func timesTimeIn(args ...tengo.Object) (ret tengo.Object, err error) {
if len(args) != 2 {
err = tengo.ErrWrongNumArguments
return
}

t1, ok := tengo.ToTime(args[0])
if !ok {
err = tengo.ErrInvalidArgumentType{
Name: "first",
Expected: "time(compatible)",
Found: args[0].TypeName(),
}
return
}

s2, ok := tengo.ToString(args[1])
if !ok {
err = tengo.ErrInvalidArgumentType{
Name: "second",
Expected: "string(compatible)",
Found: args[1].TypeName(),
}
return
}

location, err := time.LoadLocation(s2)
if err != nil {
ret = wrapError(err)
return
}

ret = &tengo.Time{Value: t1.In(location)}

return
}

func timesIsDST(args ...tengo.Object) (ret tengo.Object, err error) {
if len(args) != 1 {
err = tengo.ErrWrongNumArguments
return
}

t1, ok := tengo.ToTime(args[0])
if !ok {
err = tengo.ErrInvalidArgumentType{
Name: "first",
Expected: "time(compatible)",
Found: args[0].TypeName(),
}
return
}

if t1.IsDST() {
ret = tengo.TrueValue
} else {
ret = tengo.FalseValue
}

return
}

func timesIsZero(args ...tengo.Object) (ret tengo.Object, err error) {
if len(args) != 1 {
err = tengo.ErrWrongNumArguments
Expand Down
7 changes: 7 additions & 0 deletions stdlib/times_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,9 @@ func TestTimes(t *testing.T) {
module(t, "times").
call("parse", time.RFC3339, "1982-09-28T19:21:44+07:00").
expect(parsed)
module(t, "times").
call("parseInLocation", time.RFC3339, "1982-09-28T19:21:44+07:00", "America/Los_Angeles").
expect(parsed)
module(t, "times").
call("unix", 1234325, 94493).
expect(time.Unix(1234325, 94493))
Expand Down Expand Up @@ -80,4 +83,8 @@ func TestTimes(t *testing.T) {
module(t, "times").call("time_location", time1).
expect(time1.Location().String())
module(t, "times").call("time_string", time1).expect(time1.String())
location, _ := time.LoadLocation("America/Los_Angeles")
module(t, "times").call("time_in", time1, "America/Los_Angeles").expect(time1.In(location))
module(t, "times").call("time_location", time1.In(location)).expect("America/Los_Angeles")
module(t, "times").call("time_in", time1, "invalid location name").expectError()
}

0 comments on commit 4bb560b

Please sign in to comment.