Skip to content

Commit bd7872c

Browse files
committed
Extended times lib functionality
1 parent 0afdfde commit bd7872c

3 files changed

Lines changed: 133 additions & 0 deletions

File tree

docs/stdlib-times.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,7 @@ times := import("times")
7272
2006" would be interpreted if it were the value; it serves as an example of
7373
the input format. The same interpretation will then be made to the input
7474
string.
75+
- `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.
7576
- `unix(sec int, nsec int) => time`: returns the local Time corresponding to
7677
the given Unix time, sec seconds and nsec nanoseconds since January 1,
7778
1970 UTC.
@@ -88,6 +89,7 @@ times := import("times")
8889
- `time_month(t time) => int`: returns the month of the year specified by t.
8990
- `time_day(t time) => int`: returns the day of the month specified by t.
9091
- `time_weekday(t time) => int`: returns the day of the week specified by t.
92+
- `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.
9193
- `time_hour(t time) => int`: returns the hour within the day specified by t,
9294
in the range [0, 23].
9395
- `time_minute(t time) => int`: returns the minute offset within the hour
@@ -114,6 +116,7 @@ times := import("times")
114116
t.
115117
- `time_string(t time) => string`: returns the time formatted using the format
116118
string "2006-01-02 15:04:05.999999999 -0700 MST".
119+
- `to_location(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.
117120
- `is_zero(t time) => bool`: reports whether t represents the zero time
118121
instant, January 1, year 1, 00:00:00 UTC.
119122
- `to_local(t time) => time`: returns t with the location set to local time.

stdlib/times.go

Lines changed: 123 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -92,6 +92,10 @@ var timesModule = map[string]tengo.Object{
9292
Name: "parse",
9393
Value: timesParse,
9494
}, // parse(format, str) => time
95+
"parseInLocation": &tengo.UserFunction{
96+
Name: "parseInLocation",
97+
Value: timesParseInLocation,
98+
}, // parseInLocation(format, str, location) => time
9599
"unix": &tengo.UserFunction{
96100
Name: "unix",
97101
Value: timesUnix,
@@ -132,6 +136,10 @@ var timesModule = map[string]tengo.Object{
132136
Name: "time_weekday",
133137
Value: timesTimeWeekday,
134138
}, // time_weekday(time) => int
139+
"time_yearday": &tengo.UserFunction{
140+
Name: "time_yearday",
141+
Value: timesTimeYearday,
142+
}, // time_yearday(time) => int
135143
"time_hour": &tengo.UserFunction{
136144
Name: "time_hour",
137145
Value: timesTimeHour,
@@ -168,6 +176,10 @@ var timesModule = map[string]tengo.Object{
168176
Name: "time_string",
169177
Value: timesTimeString,
170178
}, // time_string(time) => string
179+
"to_location": &tengo.UserFunction{
180+
Name: "to_location",
181+
Value: timesToLocation,
182+
}, // to_location(time, location) => time
171183
"is_zero": &tengo.UserFunction{
172184
Name: "is_zero",
173185
Value: timesIsZero,
@@ -555,6 +567,59 @@ func timesParse(args ...tengo.Object) (ret tengo.Object, err error) {
555567
return
556568
}
557569

570+
func timesParseInLocation(args ...tengo.Object) (ret tengo.Object, err error) {
571+
if len(args) != 3 {
572+
err = tengo.ErrWrongNumArguments
573+
return
574+
}
575+
576+
s1, ok := tengo.ToString(args[0])
577+
if !ok {
578+
err = tengo.ErrInvalidArgumentType{
579+
Name: "first",
580+
Expected: "string(compatible)",
581+
Found: args[0].TypeName(),
582+
}
583+
return
584+
}
585+
586+
s2, ok := tengo.ToString(args[1])
587+
if !ok {
588+
err = tengo.ErrInvalidArgumentType{
589+
Name: "second",
590+
Expected: "string(compatible)",
591+
Found: args[1].TypeName(),
592+
}
593+
return
594+
}
595+
596+
s3, ok := tengo.ToString(args[2])
597+
if !ok {
598+
err = tengo.ErrInvalidArgumentType{
599+
Name: "third",
600+
Expected: "string(compatible)",
601+
Found: args[1].TypeName(),
602+
}
603+
return
604+
}
605+
606+
location, err := time.LoadLocation(s3)
607+
if err != nil {
608+
ret = wrapError(err)
609+
return
610+
}
611+
612+
parsed, err := time.ParseInLocation(s1, s2, location)
613+
if err != nil {
614+
ret = wrapError(err)
615+
return
616+
}
617+
618+
ret = &tengo.Time{Value: parsed}
619+
620+
return
621+
}
622+
558623
func timesUnix(args ...tengo.Object) (ret tengo.Object, err error) {
559624
if len(args) != 2 {
560625
err = tengo.ErrWrongNumArguments
@@ -853,6 +918,27 @@ func timesTimeWeekday(args ...tengo.Object) (ret tengo.Object, err error) {
853918
return
854919
}
855920

921+
func timesTimeYearday(args ...tengo.Object) (ret tengo.Object, err error) {
922+
if len(args) != 1 {
923+
err = tengo.ErrWrongNumArguments
924+
return
925+
}
926+
927+
t1, ok := tengo.ToTime(args[0])
928+
if !ok {
929+
err = tengo.ErrInvalidArgumentType{
930+
Name: "first",
931+
Expected: "time(compatible)",
932+
Found: args[0].TypeName(),
933+
}
934+
return
935+
}
936+
937+
ret = &tengo.Int{Value: int64(t1.YearDay())}
938+
939+
return
940+
}
941+
856942
func timesTimeHour(args ...tengo.Object) (ret tengo.Object, err error) {
857943
if len(args) != 1 {
858944
err = tengo.ErrWrongNumArguments
@@ -1022,6 +1108,43 @@ func timesTimeFormat(args ...tengo.Object) (ret tengo.Object, err error) {
10221108
return
10231109
}
10241110

1111+
func timesToLocation(args ...tengo.Object) (ret tengo.Object, err error) {
1112+
if len(args) != 2 {
1113+
err = tengo.ErrWrongNumArguments
1114+
return
1115+
}
1116+
1117+
t1, ok := tengo.ToTime(args[0])
1118+
if !ok {
1119+
err = tengo.ErrInvalidArgumentType{
1120+
Name: "first",
1121+
Expected: "time(compatible)",
1122+
Found: args[0].TypeName(),
1123+
}
1124+
return
1125+
}
1126+
1127+
s2, ok := tengo.ToString(args[1])
1128+
if !ok {
1129+
err = tengo.ErrInvalidArgumentType{
1130+
Name: "second",
1131+
Expected: "string(compatible)",
1132+
Found: args[1].TypeName(),
1133+
}
1134+
return
1135+
}
1136+
1137+
location, err := time.LoadLocation(s2)
1138+
if err != nil {
1139+
ret = wrapError(err)
1140+
return
1141+
}
1142+
1143+
ret = &tengo.Time{Value: t1.In(location)}
1144+
1145+
return
1146+
}
1147+
10251148
func timesIsZero(args ...tengo.Object) (ret tengo.Object, err error) {
10261149
if len(args) != 1 {
10271150
err = tengo.ErrWrongNumArguments

stdlib/times_test.go

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,9 @@ func TestTimes(t *testing.T) {
4242
module(t, "times").
4343
call("parse", time.RFC3339, "1982-09-28T19:21:44+07:00").
4444
expect(parsed)
45+
module(t, "times").
46+
call("parseInLocation", time.RFC3339, "1982-09-28T19:21:44+07:00", "America/Los_Angeles").
47+
expect(parsed)
4548
module(t, "times").
4649
call("unix", 1234325, 94493).
4750
expect(time.Unix(1234325, 94493))
@@ -80,4 +83,8 @@ func TestTimes(t *testing.T) {
8083
module(t, "times").call("time_location", time1).
8184
expect(time1.Location().String())
8285
module(t, "times").call("time_string", time1).expect(time1.String())
86+
location, _ := time.LoadLocation("America/Los_Angeles")
87+
module(t, "times").call("to_location", time1, "America/Los_Angeles").expect(time1.In(location))
88+
module(t, "times").call("time_location", time1.In(location)).expect("America/Los_Angeles")
89+
module(t, "times").call("to_location", time1, "invalid location name").expectError()
8390
}

0 commit comments

Comments
 (0)