diff --git a/pkg/yqlib/doc/operators/datetime.md b/pkg/yqlib/doc/operators/datetime.md index 7bf9c24d..bd40053e 100644 --- a/pkg/yqlib/doc/operators/datetime.md +++ b/pkg/yqlib/doc/operators/datetime.md @@ -87,7 +87,7 @@ updated: 2021-05-19T01:02:03Z ``` ## From Unix -Converts from unix time +Converts from unix time. Note, you don't have to pipe through the tz operator :) Running ```bash @@ -98,6 +98,18 @@ will output 2023-02-02T01:38:49Z ``` +## To Unix +Converts to unix time + +Running +```bash +yq --null-input 'now | to_unix' +``` +will output +```yaml +1621386123 +``` + ## Timezone: from standard RFC3339 format Returns a new datetime in the specified timezone. Specify standard IANA Time Zone format or 'utc', 'local'. When given a single parameter, this assumes the datetime is in RFC3339 format. diff --git a/pkg/yqlib/lexer_participle.go b/pkg/yqlib/lexer_participle.go index cedbd110..7e2f2284 100644 --- a/pkg/yqlib/lexer_participle.go +++ b/pkg/yqlib/lexer_participle.go @@ -46,6 +46,7 @@ var participleYqRules = []*participleYqRule{ simpleOp("now", nowOpType), simpleOp("tz", tzOpType), simpleOp("from_?unix", fromUnixOpType), + simpleOp("to_?unix", toUnixOpType), simpleOp("with_dtf", withDtFormatOpType), simpleOp("error", errorOpType), simpleOp("sortKeys", sortKeysOpType), diff --git a/pkg/yqlib/lib.go b/pkg/yqlib/lib.go index 12b299fd..0325f6af 100644 --- a/pkg/yqlib/lib.go +++ b/pkg/yqlib/lib.go @@ -94,6 +94,7 @@ var withDtFormatOpType = &operationType{Type: "WITH_DATE_TIME_FORMAT", NumArgs: var nowOpType = &operationType{Type: "NOW", NumArgs: 0, Precedence: 50, Handler: nowOp} var tzOpType = &operationType{Type: "TIMEZONE", NumArgs: 1, Precedence: 50, Handler: tzOp} var fromUnixOpType = &operationType{Type: "FROM_UNIX", NumArgs: 0, Precedence: 50, Handler: fromUnixOp} +var toUnixOpType = &operationType{Type: "TO_UNIX", NumArgs: 0, Precedence: 50, Handler: toUnixOp} var encodeOpType = &operationType{Type: "ENCODE", NumArgs: 0, Precedence: 50, Handler: encodeOperator} var decodeOpType = &operationType{Type: "DECODE", NumArgs: 0, Precedence: 50, Handler: decodeOperator} diff --git a/pkg/yqlib/operator_datetime.go b/pkg/yqlib/operator_datetime.go index f639c540..25bafa9e 100644 --- a/pkg/yqlib/operator_datetime.go +++ b/pkg/yqlib/operator_datetime.go @@ -170,3 +170,29 @@ func fromUnixOp(d *dataTreeNavigator, context Context, expressionNode *Expressio return context.ChildContext(results), nil } + +func toUnixOp(d *dataTreeNavigator, context Context, expressionNode *ExpressionNode) (Context, error) { + + layout := context.GetDateTimeLayout() + + var results = list.New() + + for el := context.MatchingNodes.Front(); el != nil; el = el.Next() { + candidate := el.Value.(*CandidateNode) + + parsedTime, err := parseDateTime(layout, candidate.Node.Value) + if err != nil { + return Context{}, fmt.Errorf("could not parse datetime of [%v] using layout [%v]: %w", candidate.GetNicePath(), layout, err) + } + + node := &yaml.Node{ + Kind: yaml.ScalarNode, + Tag: "!!int", + Value: fmt.Sprintf("%v", parsedTime.Unix()), + } + + results.PushBack(candidate.CreateReplacement(node)) + } + + return context.ChildContext(results), nil +} diff --git a/pkg/yqlib/operator_datetime_test.go b/pkg/yqlib/operator_datetime_test.go index b326a254..a2d3ca17 100644 --- a/pkg/yqlib/operator_datetime_test.go +++ b/pkg/yqlib/operator_datetime_test.go @@ -41,12 +41,20 @@ var dateTimeOperatorScenarios = []expressionScenario{ }, { description: "From Unix", - subdescription: "Converts from unix time", + subdescription: "Converts from unix time. Note, you don't have to pipe through the tz operator :)", expression: `1675301929 | from_unix | tz("UTC")`, expected: []string{ "D0, P[], (!!timestamp)::2023-02-02T01:38:49Z\n", }, }, + { + description: "To Unix", + subdescription: "Converts to unix time", + expression: `now | to_unix`, + expected: []string{ + "D0, P[], (!!int)::1621386123\n", + }, + }, { description: "Timezone: from standard RFC3339 format", subdescription: "Returns a new datetime in the specified timezone. Specify standard IANA Time Zone format or 'utc', 'local'. When given a single parameter, this assumes the datetime is in RFC3339 format.",