From 65b58a2ec0e1346caf058830f5901734ccbe74b2 Mon Sep 17 00:00:00 2001 From: Sunil Kartikey Date: Mon, 16 May 2022 13:00:22 +0100 Subject: [PATCH 1/3] feat(stdlib): added timezone support to hourSelection function issue - hourSelection() function not respecting timezone setting fixes: influxdata/EAR#3213 --- interpreter/interpreter_test.go | 4 +- libflux/go/libflux/buildinfo.gen.go | 4 +- stdlib/universe/hour_selection.go | 86 +++++++++++++++++++----- stdlib/universe/hour_selection_test.flux | 25 +++++++ stdlib/universe/universe.flux | 21 +++++- 5 files changed, 117 insertions(+), 23 deletions(-) diff --git a/interpreter/interpreter_test.go b/interpreter/interpreter_test.go index 3859df7f35..fb9ba47597 100644 --- a/interpreter/interpreter_test.go +++ b/interpreter/interpreter_test.go @@ -883,8 +883,8 @@ func TestStack(t *testing.T) { FunctionName: "window", Location: ast.SourceLocation{ File: "universe/universe.flux", - Start: ast.Position{Line: 3696, Column: 12}, - End: ast.Position{Line: 3696, Column: 51}, + Start: ast.Position{Line: 3715, Column: 12}, + End: ast.Position{Line: 3715, Column: 51}, Source: `window(every: inf, timeColumn: timeDst)`, }, }, diff --git a/libflux/go/libflux/buildinfo.gen.go b/libflux/go/libflux/buildinfo.gen.go index 96bb96dedd..c8f20cf7d8 100644 --- a/libflux/go/libflux/buildinfo.gen.go +++ b/libflux/go/libflux/buildinfo.gen.go @@ -489,7 +489,7 @@ var sourceHashes = map[string]string{ "stdlib/universe/histogram_test.flux": "a468e662ecf1adc1d9d035ff041a503cd08efe7354f096a88da12ff7edc347ef", "stdlib/universe/holt_winters_panic_test.flux": "c7681aadb9e4584b0002e47782af18c0c70734234c24adc0a631686cc3e32cb2", "stdlib/universe/holt_winters_test.flux": "47a236ef553000fb36cdf2756d32a9a923a1b478a974c1369d08d8c6ba3535f9", - "stdlib/universe/hour_selection_test.flux": "4713a9f12e529a237f9a61672577c0d09339c225658052cfc5d889a2c4bfefb3", + "stdlib/universe/hour_selection_test.flux": "b2eecf84519685941ce8fd7f873b4d85d5041c6aa5673a587f2db8cdc9c26ae3", "stdlib/universe/increase_test.flux": "dc02027842468c99c3ff0dadadde6050a2e38c7ea4bd70c7cf0a7eb10e3f93d7", "stdlib/universe/integral_columns_test.flux": "485b0319d5bbbd781cf6dbaa0cfcc56ae8d7b25ee9c02815d4b61fcfece993e9", "stdlib/universe/integral_interpolate_test.flux": "adebcba18f65e119dd3ccb0143b4de9593628765686d8932e679e85f007e786f", @@ -597,7 +597,7 @@ var sourceHashes = map[string]string{ "stdlib/universe/union_heterogeneous_test.flux": "5158d9efdf88ec10945e84f72cb7ed9669b25f967b7b4f778d2456d52ecd34da", "stdlib/universe/union_test.flux": "8529f2f609d9876f975ad648dec24eb60b569e8ac1c38e4f980e2234e68149a9", "stdlib/universe/unique_test.flux": "02180f651906f48cc57cc777d443a64bd2155394ac0ade68888f47f5900e5408", - "stdlib/universe/universe.flux": "49bf9e5b082b45dd2deec2a3281b24a068bc340797b7d466bc2a048a88d13cb6", + "stdlib/universe/universe.flux": "4dee405c283abb4d8c88a8daf5da190cfa163cc801c9568f4e85494e728c3ee6", "stdlib/universe/universe_truncateTimeColumn_test.flux": "7ca30c57336b22ae430a082d33589fa919f4558c3ed6dbe37ecde367d602435c", "stdlib/universe/window_aggregate_test.flux": "e2dba18647b2a180cafe81dd00a43077eb489421d229785e63b270eb79ddb2b1", "stdlib/universe/window_default_start_align_test.flux": "162f9d452fed411edfdcb11ef1b8ae0c565d87bbc351596d277c7db55fe67e8f", diff --git a/stdlib/universe/hour_selection.go b/stdlib/universe/hour_selection.go index c1077521fa..072b97875f 100644 --- a/stdlib/universe/hour_selection.go +++ b/stdlib/universe/hour_selection.go @@ -4,21 +4,26 @@ import ( "github.com/influxdata/flux" "github.com/influxdata/flux/codes" "github.com/influxdata/flux/execute" + "github.com/influxdata/flux/internal/date" "github.com/influxdata/flux/internal/errors" "github.com/influxdata/flux/plan" "github.com/influxdata/flux/runtime" + "github.com/influxdata/flux/semantic" + "github.com/influxdata/flux/values" ) -const HourSelectionKind = "hourSelection" +const HourSelectionKind = "_hourSelection" type HourSelectionOpSpec struct { - Start int64 `json:"start"` - Stop int64 `json:"stop"` - TimeColumn string `json:"timeColumn"` + Start int64 `json:"start"` + Stop int64 `json:"stop"` + Location string `json:"location"` + Offset values.Duration `json:"offset"` + TimeColumn string `json:"timeColumn"` } func init() { - hourSelectionSignature := runtime.MustLookupBuiltinType("universe", "hourSelection") + hourSelectionSignature := runtime.MustLookupBuiltinType("universe", "_hourSelection") runtime.RegisterPackageValue("universe", HourSelectionKind, flux.MustValue(flux.FunctionValue(HourSelectionKind, createHourSelectionOpSpec, hourSelectionSignature))) flux.RegisterOpSpec(HourSelectionKind, newHourSelectionOp) @@ -45,6 +50,13 @@ func createHourSelectionOpSpec(args flux.Arguments, a *flux.Administration) (flu } spec.Stop = stop + location, offset, err := getLocation(args) + if err != nil { + return nil, err + } + spec.Location = location + spec.Offset = offset + if label, ok, err := args.GetString("timeColumn"); err != nil { return nil, err } else if ok { @@ -66,9 +78,11 @@ func (s *HourSelectionOpSpec) Kind() flux.OperationKind { type HourSelectionProcedureSpec struct { plan.DefaultCost - Start int64 `json:"start"` - Stop int64 `json:"stop"` - TimeColumn string `json:"timeColumn"` + Start int64 `json:"start"` + Stop int64 `json:"stop"` + Location string `json:"location"` + Offset values.Duration `json:"offset"` + TimeColumn string `json:"timeColumn"` } func newHourSelectionProcedure(qs flux.OperationSpec, pa plan.Administration) (plan.ProcedureSpec, error) { @@ -80,6 +94,8 @@ func newHourSelectionProcedure(qs flux.OperationSpec, pa plan.Administration) (p return &HourSelectionProcedureSpec{ Start: spec.Start, Stop: spec.Stop, + Location: spec.Location, + Offset: spec.Offset, TimeColumn: spec.TimeColumn, }, nil } @@ -116,18 +132,22 @@ type hourSelectionTransformation struct { d execute.Dataset cache execute.TableBuilderCache - start int64 - stop int64 - timeCol string + start int64 + stop int64 + location string + offset values.Duration + timeCol string } func NewHourSelectionTransformation(d execute.Dataset, cache execute.TableBuilderCache, spec *HourSelectionProcedureSpec) *hourSelectionTransformation { return &hourSelectionTransformation{ - d: d, - cache: cache, - start: spec.Start, - stop: spec.Stop, - timeCol: spec.TimeColumn, + d: d, + cache: cache, + start: spec.Start, + stop: spec.Stop, + location: spec.Location, + offset: spec.Offset, + timeCol: spec.TimeColumn, } } @@ -162,8 +182,12 @@ func (t *hourSelectionTransformation) Process(id execute.DatasetID, tbl flux.Tab if nullCheck := cr.Times(colIdx); nullCheck.IsNull(i) { continue } - curr := execute.Time(cr.Times(colIdx).Value(i)).Time().Hour() - if (int64(curr) >= t.start && int64(curr) <= t.stop) || (t.start > t.stop && (int64(curr) >= t.start || int64(curr) <= t.stop)) { + lTime, err := date.GetTimeInLocation(execute.Time(cr.Times(colIdx).Value(i)), t.location, t.offset) + if err != nil { + return nil + } + lHour := int64(lTime.Time().Time().Hour()) + if (lHour >= t.start && lHour <= t.stop) || (t.start > t.stop && (lHour >= t.start || lHour <= t.stop)) { for k := range cr.Cols() { if err := builder.AppendValue(k, execute.ValueForRow(cr, i, k)); err != nil { return err @@ -184,3 +208,29 @@ func (t *hourSelectionTransformation) UpdateProcessingTime(id execute.DatasetID, func (t *hourSelectionTransformation) Finish(id execute.DatasetID, err error) { t.d.Finish(err) } + +func getLocation(args flux.Arguments) (string, values.Duration, error) { + var name, offset values.Value + var ok bool + if location, err := args.GetRequiredObject("location"); err != nil { + return "UTC", values.ConvertDurationNsecs(0), err + } else { + name, ok = location.Get("zone") + if !ok { + return "UTC", values.ConvertDurationNsecs(0), errors.New(codes.Invalid, "zone property missing from location record") + } else if got := name.Type().Nature(); got != semantic.String { + return "UTC", values.ConvertDurationNsecs(0), errors.Newf(codes.Invalid, "zone property for location must be of type %s, got %s", semantic.String, got) + } + + if offset, ok = location.Get("offset"); ok { + if got := offset.Type().Nature(); got != semantic.Duration { + return "UTC", values.ConvertDurationNsecs(0), errors.Newf(codes.Invalid, "offset property for location must be of type %s, got %s", semantic.Duration, got) + } + } + } + if name.IsNull() { + name = values.NewString("UTC") + } + + return name.Str(), offset.Duration(), nil +} diff --git a/stdlib/universe/hour_selection_test.flux b/stdlib/universe/hour_selection_test.flux index 97a11f0bc2..d7a507e24b 100644 --- a/stdlib/universe/hour_selection_test.flux +++ b/stdlib/universe/hour_selection_test.flux @@ -3,6 +3,7 @@ package universe_test import "testing" import "csv" +import "timezone" option now = () => 2030-01-01T00:00:00Z @@ -65,3 +66,27 @@ testcase hour_selection_overnight_range { testing.diff(got: got, want: want) } + +testcase hour_selection_location { + option location = timezone.location(name: "America/Los_Angeles") + + got = + csv.from(csv: inData) + |> range(start: 2018-12-01T00:00:00Z) + |> hourSelection(start: 9, stop: 10, timeColumn: "_time") + + want = + csv.from( + csv: + " +#datatype,string,long,dateTime:RFC3339,dateTime:RFC3339,string,string,dateTime:RFC3339,unsignedLong +#group,false,false,true,true,true,true,false,false +#default,_result,,,,,,, +,result,table,_start,_stop,_measurement,_field,_time,_value +,,0,2018-12-01T00:00:00Z,2030-01-01T00:00:00Z,Sgf,DlXwgrw,2018-12-18T17:11:25Z,33 +,,0,2018-12-01T00:00:00Z,2030-01-01T00:00:00Z,Sgf,DlXwgrw,2018-12-19T18:11:35Z,63 +", + ) + + testing.diff(got: got, want: want) + } diff --git a/stdlib/universe/universe.flux b/stdlib/universe/universe.flux index a57ab7e11d..e5b07b0458 100644 --- a/stdlib/universe/universe.flux +++ b/stdlib/universe/universe.flux @@ -937,6 +937,17 @@ builtin holtWinters : ( A: Record, B: Record +// builtin _hourSelection used by hourSelection +builtin _hourSelection : ( + <-tables: stream[A], + start: int, + stop: int, + location: {zone: string, offset: duration}, + ?timeColumn: string, + ) => stream[A] + where + A: Record + // hourSelection filters rows by time values in a specified hour range. // // ## Parameters @@ -970,7 +981,15 @@ builtin holtWinters : ( // introduced: 0.39.0 // tags: transformations, date/time, filters // -builtin hourSelection : (<-tables: stream[A], start: int, stop: int, ?timeColumn: string) => stream[A] where A: Record +hourSelection = ( + tables=<-, + start, + stop, + location=location, + timeColumn="_time", +) => + tables + |> _hourSelection(start, stop, location, timeColumn) // integral computes the area under the curve per unit of time of subsequent non-null records. // From 37f8fb0534ff18abcf62168b74a3f284f6fe0aff Mon Sep 17 00:00:00 2001 From: Sunil Kartikey Date: Mon, 16 May 2022 19:26:22 +0100 Subject: [PATCH 2/3] fix: added missing doc and exported method from date package --- stdlib/date/date.go | 28 ++++++++++++++++------------ stdlib/universe/hour_selection.go | 30 ++---------------------------- stdlib/universe/universe.flux | 1 + 3 files changed, 19 insertions(+), 40 deletions(-) diff --git a/stdlib/date/date.go b/stdlib/date/date.go index f63cda8853..421b409682 100644 --- a/stdlib/date/date.go +++ b/stdlib/date/date.go @@ -39,7 +39,7 @@ func init() { if err != nil { return nil, err } - location, offset, err := getLocationFromArgs(args) + location, offset, err := getLocationFromObjArgs(args) if err != nil { return nil, err } @@ -58,7 +58,7 @@ func init() { if err != nil { return nil, err } - location, offset, err := getLocationFromArgs(args) + location, offset, err := getLocationFromObjArgs(args) if err != nil { return nil, err } @@ -77,7 +77,7 @@ func init() { if err != nil { return nil, err } - location, offset, err := getLocationFromArgs(args) + location, offset, err := getLocationFromObjArgs(args) if err != nil { return nil, err } @@ -96,7 +96,7 @@ func init() { if err != nil { return nil, err } - location, offset, err := getLocationFromArgs(args) + location, offset, err := getLocationFromObjArgs(args) if err != nil { return nil, err } @@ -115,7 +115,7 @@ func init() { if err != nil { return nil, err } - location, offset, err := getLocationFromArgs(args) + location, offset, err := getLocationFromObjArgs(args) if err != nil { return nil, err } @@ -134,7 +134,7 @@ func init() { if err != nil { return nil, err } - location, offset, err := getLocationFromArgs(args) + location, offset, err := getLocationFromObjArgs(args) if err != nil { return nil, err } @@ -153,7 +153,7 @@ func init() { if err != nil { return nil, err } - location, offset, err := getLocationFromArgs(args) + location, offset, err := getLocationFromObjArgs(args) if err != nil { return nil, err } @@ -172,7 +172,7 @@ func init() { if err != nil { return nil, err } - location, offset, err := getLocationFromArgs(args) + location, offset, err := getLocationFromObjArgs(args) if err != nil { return nil, err } @@ -192,7 +192,7 @@ func init() { if err != nil { return nil, err } - location, offset, err := getLocationFromArgs(args) + location, offset, err := getLocationFromObjArgs(args) if err != nil { return nil, err } @@ -262,7 +262,7 @@ func init() { if err != nil { return nil, err } - location, _, err := getLocationFromArgs(args) + location, _, err := getLocationFromObjArgs(args) if err != nil { return nil, err } @@ -307,9 +307,13 @@ func getTime(args values.Object) (values.Value, error) { return tArg, nil } -func getLocationFromArgs(args values.Object) (string, values.Duration, error) { +func getLocationFromObjArgs(args values.Object) (string, values.Duration, error) { a := interpreter.NewArguments(args) - location, err := a.GetRequiredObject("location") + return GetLocationFromFluxArgs(a) +} + +func GetLocationFromFluxArgs(args interpreter.Arguments) (string, values.Duration, error) { + location, err := args.GetRequiredObject("location") if err != nil { return "UTC", values.ConvertDurationNsecs(0), err } diff --git a/stdlib/universe/hour_selection.go b/stdlib/universe/hour_selection.go index 072b97875f..8cd9622ca7 100644 --- a/stdlib/universe/hour_selection.go +++ b/stdlib/universe/hour_selection.go @@ -8,7 +8,7 @@ import ( "github.com/influxdata/flux/internal/errors" "github.com/influxdata/flux/plan" "github.com/influxdata/flux/runtime" - "github.com/influxdata/flux/semantic" + datepackage "github.com/influxdata/flux/stdlib/date" "github.com/influxdata/flux/values" ) @@ -50,7 +50,7 @@ func createHourSelectionOpSpec(args flux.Arguments, a *flux.Administration) (flu } spec.Stop = stop - location, offset, err := getLocation(args) + location, offset, err := datepackage.GetLocationFromFluxArgs(args) if err != nil { return nil, err } @@ -208,29 +208,3 @@ func (t *hourSelectionTransformation) UpdateProcessingTime(id execute.DatasetID, func (t *hourSelectionTransformation) Finish(id execute.DatasetID, err error) { t.d.Finish(err) } - -func getLocation(args flux.Arguments) (string, values.Duration, error) { - var name, offset values.Value - var ok bool - if location, err := args.GetRequiredObject("location"); err != nil { - return "UTC", values.ConvertDurationNsecs(0), err - } else { - name, ok = location.Get("zone") - if !ok { - return "UTC", values.ConvertDurationNsecs(0), errors.New(codes.Invalid, "zone property missing from location record") - } else if got := name.Type().Nature(); got != semantic.String { - return "UTC", values.ConvertDurationNsecs(0), errors.Newf(codes.Invalid, "zone property for location must be of type %s, got %s", semantic.String, got) - } - - if offset, ok = location.Get("offset"); ok { - if got := offset.Type().Nature(); got != semantic.Duration { - return "UTC", values.ConvertDurationNsecs(0), errors.Newf(codes.Invalid, "offset property for location must be of type %s, got %s", semantic.Duration, got) - } - } - } - if name.IsNull() { - name = values.NewString("UTC") - } - - return name.Str(), offset.Duration(), nil -} diff --git a/stdlib/universe/universe.flux b/stdlib/universe/universe.flux index e5b07b0458..4901b69b6c 100644 --- a/stdlib/universe/universe.flux +++ b/stdlib/universe/universe.flux @@ -953,6 +953,7 @@ builtin _hourSelection : ( // ## Parameters // - start: First hour of the hour range (inclusive). Hours range from `[0-23]`. // - stop: Last hour of the hour range (inclusive). Hours range from `[0-23]`. +// - location: Location used to determine timezone. Default is the `location` option. // - timeColumn: Column that contains the time value. Default is `_time`. // - tables: Input data. Default is piped-forward data (`<-`). // From 7eeac7ae0e297d5e8923fd770d5cb400820e426c Mon Sep 17 00:00:00 2001 From: Sunil Kartikey Date: Mon, 16 May 2022 20:25:44 +0100 Subject: [PATCH 3/3] chore: moved date exported method to internal package --- internal/date/date.go | 40 +++++++++++++++++++ interpreter/interpreter_test.go | 4 +- libflux/go/libflux/buildinfo.gen.go | 2 +- stdlib/date/date.go | 60 +++++------------------------ stdlib/date/durations.go | 3 +- stdlib/universe/hour_selection.go | 3 +- 6 files changed, 56 insertions(+), 56 deletions(-) diff --git a/internal/date/date.go b/internal/date/date.go index 30a7fb873e..9131f97566 100644 --- a/internal/date/date.go +++ b/internal/date/date.go @@ -4,6 +4,8 @@ import ( "github.com/influxdata/flux/codes" "github.com/influxdata/flux/internal/errors" "github.com/influxdata/flux/internal/zoneinfo" + "github.com/influxdata/flux/interpreter" + "github.com/influxdata/flux/semantic" "github.com/influxdata/flux/values" ) @@ -25,3 +27,41 @@ func GetTimeInLocation(t values.Time, location string, offset values.Duration) ( } return values.NewTime(t), nil } + +func GetLocationFromObjArgs(args values.Object) (string, values.Duration, error) { + a := interpreter.NewArguments(args) + return GetLocationFromFluxArgs(a) +} + +func GetLocationFromFluxArgs(args interpreter.Arguments) (string, values.Duration, error) { + location, err := args.GetRequiredObject("location") + if err != nil { + return "UTC", values.ConvertDurationNsecs(0), err + } + return GetLocation(location) +} + +func GetLocation(location values.Object) (string, values.Duration, error) { + var ( + name, offset values.Value + ok bool + ) + + name, ok = location.Get("zone") + if !ok { + return "UTC", values.ConvertDurationNsecs(0), errors.New(codes.Invalid, "zone property missing from location record") + } else if got := name.Type().Nature(); got != semantic.String { + return "UTC", values.ConvertDurationNsecs(0), errors.Newf(codes.Invalid, "zone property for location must be of type %s, got %s", semantic.String, got) + } + + if offset, ok = location.Get("offset"); ok { + if got := offset.Type().Nature(); got != semantic.Duration { + return "UTC", values.ConvertDurationNsecs(0), errors.Newf(codes.Invalid, "offset property for location must be of type %s, got %s", semantic.Duration, got) + } + } + + if name.IsNull() { + return "UTC", offset.Duration(), nil + } + return name.Str(), offset.Duration(), nil +} diff --git a/interpreter/interpreter_test.go b/interpreter/interpreter_test.go index fb9ba47597..6118915c3e 100644 --- a/interpreter/interpreter_test.go +++ b/interpreter/interpreter_test.go @@ -883,8 +883,8 @@ func TestStack(t *testing.T) { FunctionName: "window", Location: ast.SourceLocation{ File: "universe/universe.flux", - Start: ast.Position{Line: 3715, Column: 12}, - End: ast.Position{Line: 3715, Column: 51}, + Start: ast.Position{Line: 3716, Column: 12}, + End: ast.Position{Line: 3716, Column: 51}, Source: `window(every: inf, timeColumn: timeDst)`, }, }, diff --git a/libflux/go/libflux/buildinfo.gen.go b/libflux/go/libflux/buildinfo.gen.go index c8f20cf7d8..fecb743a68 100644 --- a/libflux/go/libflux/buildinfo.gen.go +++ b/libflux/go/libflux/buildinfo.gen.go @@ -597,7 +597,7 @@ var sourceHashes = map[string]string{ "stdlib/universe/union_heterogeneous_test.flux": "5158d9efdf88ec10945e84f72cb7ed9669b25f967b7b4f778d2456d52ecd34da", "stdlib/universe/union_test.flux": "8529f2f609d9876f975ad648dec24eb60b569e8ac1c38e4f980e2234e68149a9", "stdlib/universe/unique_test.flux": "02180f651906f48cc57cc777d443a64bd2155394ac0ade68888f47f5900e5408", - "stdlib/universe/universe.flux": "4dee405c283abb4d8c88a8daf5da190cfa163cc801c9568f4e85494e728c3ee6", + "stdlib/universe/universe.flux": "c8a3bbd18143113965ca29f94e8ff86c68eea21427fb1e971b4b8334ff2f8802", "stdlib/universe/universe_truncateTimeColumn_test.flux": "7ca30c57336b22ae430a082d33589fa919f4558c3ed6dbe37ecde367d602435c", "stdlib/universe/window_aggregate_test.flux": "e2dba18647b2a180cafe81dd00a43077eb489421d229785e63b270eb79ddb2b1", "stdlib/universe/window_default_start_align_test.flux": "162f9d452fed411edfdcb11ef1b8ae0c565d87bbc351596d277c7db55fe67e8f", diff --git a/stdlib/date/date.go b/stdlib/date/date.go index 421b409682..d7f3efc8fd 100644 --- a/stdlib/date/date.go +++ b/stdlib/date/date.go @@ -9,10 +9,8 @@ import ( "github.com/influxdata/flux/execute" "github.com/influxdata/flux/internal/date" "github.com/influxdata/flux/internal/errors" - "github.com/influxdata/flux/interpreter" "github.com/influxdata/flux/interval" "github.com/influxdata/flux/runtime" - "github.com/influxdata/flux/semantic" "github.com/influxdata/flux/values" ) @@ -39,7 +37,7 @@ func init() { if err != nil { return nil, err } - location, offset, err := getLocationFromObjArgs(args) + location, offset, err := date.GetLocationFromObjArgs(args) if err != nil { return nil, err } @@ -58,7 +56,7 @@ func init() { if err != nil { return nil, err } - location, offset, err := getLocationFromObjArgs(args) + location, offset, err := date.GetLocationFromObjArgs(args) if err != nil { return nil, err } @@ -77,7 +75,7 @@ func init() { if err != nil { return nil, err } - location, offset, err := getLocationFromObjArgs(args) + location, offset, err := date.GetLocationFromObjArgs(args) if err != nil { return nil, err } @@ -96,7 +94,7 @@ func init() { if err != nil { return nil, err } - location, offset, err := getLocationFromObjArgs(args) + location, offset, err := date.GetLocationFromObjArgs(args) if err != nil { return nil, err } @@ -115,7 +113,7 @@ func init() { if err != nil { return nil, err } - location, offset, err := getLocationFromObjArgs(args) + location, offset, err := date.GetLocationFromObjArgs(args) if err != nil { return nil, err } @@ -134,7 +132,7 @@ func init() { if err != nil { return nil, err } - location, offset, err := getLocationFromObjArgs(args) + location, offset, err := date.GetLocationFromObjArgs(args) if err != nil { return nil, err } @@ -153,7 +151,7 @@ func init() { if err != nil { return nil, err } - location, offset, err := getLocationFromObjArgs(args) + location, offset, err := date.GetLocationFromObjArgs(args) if err != nil { return nil, err } @@ -172,7 +170,7 @@ func init() { if err != nil { return nil, err } - location, offset, err := getLocationFromObjArgs(args) + location, offset, err := date.GetLocationFromObjArgs(args) if err != nil { return nil, err } @@ -192,7 +190,7 @@ func init() { if err != nil { return nil, err } - location, offset, err := getLocationFromObjArgs(args) + location, offset, err := date.GetLocationFromObjArgs(args) if err != nil { return nil, err } @@ -262,7 +260,7 @@ func init() { if err != nil { return nil, err } - location, _, err := getLocationFromObjArgs(args) + location, _, err := date.GetLocationFromObjArgs(args) if err != nil { return nil, err } @@ -307,44 +305,6 @@ func getTime(args values.Object) (values.Value, error) { return tArg, nil } -func getLocationFromObjArgs(args values.Object) (string, values.Duration, error) { - a := interpreter.NewArguments(args) - return GetLocationFromFluxArgs(a) -} - -func GetLocationFromFluxArgs(args interpreter.Arguments) (string, values.Duration, error) { - location, err := args.GetRequiredObject("location") - if err != nil { - return "UTC", values.ConvertDurationNsecs(0), err - } - return getLocation(location) -} - -func getLocation(location values.Object) (string, values.Duration, error) { - var ( - name, offset values.Value - ok bool - ) - - name, ok = location.Get("zone") - if !ok { - return "UTC", values.ConvertDurationNsecs(0), errors.New(codes.Invalid, "zone property missing from location record") - } else if got := name.Type().Nature(); got != semantic.String { - return "UTC", values.ConvertDurationNsecs(0), errors.Newf(codes.Invalid, "zone property for location must be of type %s, got %s", semantic.String, got) - } - - if offset, ok = location.Get("offset"); ok { - if got := offset.Type().Nature(); got != semantic.Duration { - return "UTC", values.ConvertDurationNsecs(0), errors.Newf(codes.Invalid, "offset property for location must be of type %s, got %s", semantic.Duration, got) - } - } - - if name.IsNull() { - return "UTC", offset.Duration(), nil - } - return name.Str(), offset.Duration(), nil -} - func getTimeableTime(ctx context.Context, args values.Object) (values.Time, error) { var tm values.Time t, err := getTime(args) diff --git a/stdlib/date/durations.go b/stdlib/date/durations.go index e6988f1f92..34ea3d7b82 100644 --- a/stdlib/date/durations.go +++ b/stdlib/date/durations.go @@ -5,6 +5,7 @@ import ( "github.com/influxdata/flux/codes" "github.com/influxdata/flux/execute" + "github.com/influxdata/flux/internal/date" "github.com/influxdata/flux/internal/errors" "github.com/influxdata/flux/internal/function" "github.com/influxdata/flux/internal/zoneinfo" @@ -63,7 +64,7 @@ func addDuration(ctx context.Context, t values.Value, d values.Duration, scale i return nil, err } - name, offset, err := getLocation(loc) + name, offset, err := date.GetLocation(loc) if err != nil { return nil, err } diff --git a/stdlib/universe/hour_selection.go b/stdlib/universe/hour_selection.go index 8cd9622ca7..1387edf6a3 100644 --- a/stdlib/universe/hour_selection.go +++ b/stdlib/universe/hour_selection.go @@ -8,7 +8,6 @@ import ( "github.com/influxdata/flux/internal/errors" "github.com/influxdata/flux/plan" "github.com/influxdata/flux/runtime" - datepackage "github.com/influxdata/flux/stdlib/date" "github.com/influxdata/flux/values" ) @@ -50,7 +49,7 @@ func createHourSelectionOpSpec(args flux.Arguments, a *flux.Administration) (flu } spec.Stop = stop - location, offset, err := datepackage.GetLocationFromFluxArgs(args) + location, offset, err := date.GetLocationFromFluxArgs(args) if err != nil { return nil, err }