11package time
22
33import (
4- "errors"
54 "fmt"
65 "sort"
76 "time"
@@ -15,12 +14,12 @@ import (
1514var Module = & starlarkstruct.Module {
1615 Name : "time" ,
1716 Members : starlark.StringDict {
18- "parse_duration" : starlark .NewBuiltin ("parse_duration" , parseDuration ),
19- "parse_location " : starlark .NewBuiltin ("parse_location " , parseLocation ),
20- "now" : starlark .NewBuiltin ("now" , now ),
21- "time" : starlark .NewBuiltin ("time" , newTime ),
22- "parse_time" : starlark .NewBuiltin ("time " , parseTime ),
23- "from_timestamp" : starlark .NewBuiltin ("from_timestamp" , fromTimestamp ),
17+ "parse_duration" : starlark .NewBuiltin ("parse_duration" , parseDuration ),
18+ "is_valid_timezone " : starlark .NewBuiltin ("is_valid_timezone " , isValidTimezone ),
19+ "now" : starlark .NewBuiltin ("now" , now ),
20+ "time" : starlark .NewBuiltin ("time" , newTime ),
21+ "parse_time" : starlark .NewBuiltin ("parse_time " , parseTime ),
22+ "from_timestamp" : starlark .NewBuiltin ("from_timestamp" , fromTimestamp ),
2423
2524 "nanosecond" : Duration (time .Nanosecond ),
2625 "microsecond" : Duration (time .Microsecond ),
@@ -36,35 +35,42 @@ var Module = &starlarkstruct.Module{
3635// Starlark scripts to be fully deterministic.
3736var NowFunc = time .Now
3837
38+ // Parses the given duration string.
39+ // A duration string is a possibly signed sequence of
40+ // decimal numbers, each with optional fraction and a unit suffix,
41+ // such as "300ms", "-1.5h" or "2h45m".
42+ // Valid time units are "ns", "us" (or "µs"), "ms", "s", "m", "h".
3943func parseDuration (thread * starlark.Thread , _ * starlark.Builtin , args starlark.Tuple , kwargs []starlark.Tuple ) (starlark.Value , error ) {
4044 var d Duration
4145 err := starlark .UnpackPositionalArgs ("duration" , args , kwargs , 1 , & d )
4246 return d , err
4347}
4448
45- func parseLocation (thread * starlark.Thread , _ * starlark.Builtin , args starlark.Tuple , kwargs []starlark.Tuple ) (starlark.Value , error ) {
49+ // Indicates whether the given name of location is valid or not.
50+ // Returns true if it is valid, false otherwise.
51+ func isValidTimezone (thread * starlark.Thread , _ * starlark.Builtin , args starlark.Tuple , kwargs []starlark.Tuple ) (starlark.Value , error ) {
4652 var s string
47- if err := starlark .UnpackPositionalArgs ("location " , args , kwargs , 1 , & s ); err != nil {
53+ if err := starlark .UnpackPositionalArgs ("is_valid_timezone " , args , kwargs , 1 , & s ); err != nil {
4854 return nil , err
4955 }
50- loc , err := time .LoadLocation (s )
51- if err != nil {
52- return nil , err
53- }
54-
55- return starlark .String (loc .String ()), nil
56+ _ , err := time .LoadLocation (s )
57+ return starlark .Bool (err == nil ), nil
5658}
5759
60+ // The expected arguments are a time string (mandatory), a time format (optional by default it is RFC3339)
61+ // and a name of location (optional by default is UTC).
62+ // Parses the given time string using a specific time format and location.
5863func parseTime (thread * starlark.Thread , _ * starlark.Builtin , args starlark.Tuple , kwargs []starlark.Tuple ) (starlark.Value , error ) {
5964 var (
60- x , location string
61- format = time .RFC3339
65+ x string
66+ location = "UTC"
67+ format = time .RFC3339
6268 )
6369 if err := starlark .UnpackArgs ("time" , args , kwargs , "x" , & x , "format?" , & format , "location?" , & location ); err != nil {
6470 return nil , err
6571 }
6672
67- if location == "" {
73+ if location == "UTC " {
6874 t , err := time .Parse (format , x )
6975 if err != nil {
7076 return nil , err
@@ -83,6 +89,8 @@ func parseTime(thread *starlark.Thread, _ *starlark.Builtin, args starlark.Tuple
8389 return Time (t ), nil
8490}
8591
92+ // Parses the given timestamp string corresponding to
93+ // the total amount of seconds since January 1, 1970 UTC.
8694func fromTimestamp (thread * starlark.Thread , _ * starlark.Builtin , args starlark.Tuple , kwargs []starlark.Tuple ) (starlark.Value , error ) {
8795 var x int64
8896 if err := starlark .UnpackPositionalArgs ("from_timestamp" , args , kwargs , 1 , & x ); err != nil {
@@ -91,14 +99,15 @@ func fromTimestamp(thread *starlark.Thread, _ *starlark.Builtin, args starlark.T
9199 return Time (time .Unix (x , 0 )), nil
92100}
93101
102+ // Generates the current time current time.
94103func now (thread * starlark.Thread , _ * starlark.Builtin , args starlark.Tuple , kwargs []starlark.Tuple ) (starlark.Value , error ) {
95104 return Time (NowFunc ()), nil
96105}
97106
98107// Duration is a Starlark representation of a duration.
99108type Duration time.Duration
100109
101- // assert at compile time that Duration implements Unpacker.
110+ // Assert at compile time that Duration implements Unpacker.
102111var _ starlark.Unpacker = (* Duration )(nil )
103112
104113// Unpack is a custom argument unpacker
@@ -191,7 +200,7 @@ func (d Duration) CompareSameType(op syntax.Token, v starlark.Value, depth int)
191200 case syntax .GE :
192201 return x >= y , nil
193202 }
194- return false , errors . New ( "operation not supported" )
203+ return threeway ( op , x - y ), nil
195204}
196205
197206// Binary implements binary operators, which satisfies the starlark.HasBinary
@@ -203,7 +212,6 @@ func (d Duration) CompareSameType(op syntax.Token, v starlark.Value, depth int)
203212// duration / int = duration
204213// duration / float = duration
205214// duration // duration = int
206- // duration // int = duration
207215// duration * int = duration
208216func (d Duration ) Binary (op syntax.Token , y starlark.Value , side starlark.Side ) (starlark.Value , error ) {
209217 x := time .Duration (d )
@@ -226,10 +234,10 @@ func (d Duration) Binary(op syntax.Token, y starlark.Value, side starlark.Side)
226234 case syntax .SLASH :
227235 switch y := y .(type ) {
228236 case Duration :
229- if int64 ( y ) == 0 {
237+ if y == 0 {
230238 return nil , fmt .Errorf ("%s division by zero" , d .Type ())
231239 }
232- return starlark .Float (float64 ( x .Nanoseconds ()) / float64 (time .Duration (y ).Nanoseconds () )), nil
240+ return starlark .Float (x .Nanoseconds ()) / starlark . Float (time .Duration (y ).Nanoseconds ()), nil
233241 case starlark.Int :
234242 if side == starlark .Right {
235243 return nil , fmt .Errorf ("unsupported operation" )
@@ -238,10 +246,10 @@ func (d Duration) Binary(op syntax.Token, y starlark.Value, side starlark.Side)
238246 if ! ok {
239247 return nil , fmt .Errorf ("int value out of range (want signed 64-bit value)" )
240248 }
241- if int64 ( i ) == 0 {
249+ if i == 0 {
242250 return nil , fmt .Errorf ("%s division by zero" , d .Type ())
243251 }
244- return Duration ( x . Nanoseconds () / i ), nil
252+ return d / Duration ( i ), nil
245253 case starlark.Float :
246254 f := float64 (y )
247255 if f == 0 {
@@ -253,22 +261,10 @@ func (d Duration) Binary(op syntax.Token, y starlark.Value, side starlark.Side)
253261 case syntax .SLASHSLASH :
254262 switch y := y .(type ) {
255263 case Duration :
256- if int64 ( y ) == 0 {
264+ if y == 0 {
257265 return nil , fmt .Errorf ("%s division by zero" , d .Type ())
258266 }
259267 return starlark .MakeInt64 (x .Nanoseconds () / time .Duration (y ).Nanoseconds ()), nil
260- case starlark.Int :
261- if side == starlark .Right {
262- return nil , fmt .Errorf ("unsupported operation" )
263- }
264- i , ok := y .Int64 ()
265- if ! ok {
266- return nil , fmt .Errorf ("int value out of range (want signed 64-bit value)" )
267- }
268- if int64 (i ) == 0 {
269- return nil , fmt .Errorf ("%s division by zero" , d .Type ())
270- }
271- return d / Duration (i ), nil
272268 }
273269
274270 case syntax .STAR :
@@ -285,7 +281,7 @@ func (d Duration) Binary(op syntax.Token, y starlark.Value, side starlark.Side)
285281 return nil , nil
286282}
287283
288- // Time is a starlark representation of a moment in time.
284+ // Time is a Starlark representation of a moment in time.
289285type Time time.Time
290286
291287func newTime (thread * starlark.Thread , _ * starlark.Builtin , args starlark.Tuple , kwargs []starlark.Tuple ) (starlark.Value , error ) {
@@ -316,7 +312,7 @@ func newTime(thread *starlark.Thread, _ *starlark.Builtin, args starlark.Tuple,
316312}
317313
318314// String returns the time formatted using the format string
319- // "2006-01-02 15:04:05.999999999 -0700 MST"
315+ // "2006-01-02 15:04:05.999999999 -0700 MST".
320316func (t Time ) String () string { return time .Time (t ).String () }
321317
322318// Type returns "time.time".
@@ -472,7 +468,7 @@ func builtinAttrNames(methods map[string]builtinMethod) []string {
472468 return names
473469}
474470
475- // threeway interprets a three-way comparison value cmp (-1, 0, +1)
471+ // Threeway interprets a three-way comparison value cmp (-1, 0, +1)
476472// as a boolean comparison (e.g. x < y).
477473func threeway (op syntax.Token , cmp int ) bool {
478474 switch op {
0 commit comments