From 995025b5728e6c9a8bf833f5cab554b06ed4d60e Mon Sep 17 00:00:00 2001 From: Kjell Winblad Date: Mon, 29 May 2023 14:22:58 +0200 Subject: [PATCH] feat: add timezone_to_second/1 function to rule engine This commit adds the functions timezone_to_offset_seconds and its alias timezone_to_second to the rule engine. As the names suggests, these functions convert a timzone offset string such as "+02:00", "Z", "local" to an integer representing how many seconds that the given timezone differs from UTC. timezone_to_offset_seconds is the one of the two functions that should be advertised while timezone_to_second in kept for backwards compatibility with 4.X. Fixes: https://emqx.atlassian.net/browse/EMQX-10058 --- apps/emqx_machine/src/emqx_machine.app.src | 2 +- apps/emqx_rule_engine/src/emqx_rule_funcs.erl | 10 +++++++++- .../test/emqx_rule_funcs_SUITE.erl | 19 +++++++++++++++++++ 3 files changed, 29 insertions(+), 2 deletions(-) diff --git a/apps/emqx_machine/src/emqx_machine.app.src b/apps/emqx_machine/src/emqx_machine.app.src index 7cf0e4b53..5cfa80369 100644 --- a/apps/emqx_machine/src/emqx_machine.app.src +++ b/apps/emqx_machine/src/emqx_machine.app.src @@ -3,7 +3,7 @@ {id, "emqx_machine"}, {description, "The EMQX Machine"}, % strict semver, bump manually! - {vsn, "0.2.4"}, + {vsn, "0.2.5"}, {modules, []}, {registered, []}, {applications, [kernel, stdlib, emqx_ctl]}, diff --git a/apps/emqx_rule_engine/src/emqx_rule_funcs.erl b/apps/emqx_rule_engine/src/emqx_rule_funcs.erl index 73e2f78e7..a94aa0c8a 100644 --- a/apps/emqx_rule_engine/src/emqx_rule_funcs.erl +++ b/apps/emqx_rule_engine/src/emqx_rule_funcs.erl @@ -228,7 +228,9 @@ format_date/3, format_date/4, date_to_unix_ts/3, - date_to_unix_ts/4 + date_to_unix_ts/4, + timezone_to_second/1, + timezone_to_offset_seconds/1 ]). %% MongoDB specific date functions. These functions return a date tuple. The @@ -1104,6 +1106,12 @@ date_to_unix_ts(TimeUnit, Offset, FormatString, InputString) -> OffsetDelta = erlang:convert_time_unit(OffsetSecond, second, Unit), date_to_unix_ts(Unit, FormatString, InputString) - OffsetDelta. +timezone_to_second(TimeZone) -> + timezone_to_offset_seconds(TimeZone). + +timezone_to_offset_seconds(TimeZone) -> + emqx_calendar:offset_second(TimeZone). + %% @doc This is for sql funcs that should be handled in the specific modules. %% Here the emqx_rule_funcs module acts as a proxy, forwarding %% the function handling to the worker module. diff --git a/apps/emqx_rule_engine/test/emqx_rule_funcs_SUITE.erl b/apps/emqx_rule_engine/test/emqx_rule_funcs_SUITE.erl index 9bb6e2e6f..525d60503 100644 --- a/apps/emqx_rule_engine/test/emqx_rule_funcs_SUITE.erl +++ b/apps/emqx_rule_engine/test/emqx_rule_funcs_SUITE.erl @@ -1012,6 +1012,25 @@ prop_format_date_fun() -> Args3DTUS = [<<"second">>, <<"+04:00">>, <<"--%m--%d--%Y---%H:%M:%S">>, Formatters3], Second == apply_func(date_to_unix_ts, Args3DTUS). +t_timezone_to_offset_seconds(_) -> + t_timezone_to_offset_seconds_helper(timezone_to_offset_seconds), + %% The timezone_to_second function is kept for compatibility with 4.X. + t_timezone_to_offset_seconds_helper(timezone_to_second). + +t_timezone_to_offset_seconds_helper(FunctionName) -> + ?assertEqual(120 * 60, apply_func(FunctionName, [<<"+02:00:00">>])), + ?assertEqual(-120 * 60, apply_func(FunctionName, [<<"-02:00:00">>])), + ?assertEqual(102, apply_func(FunctionName, [<<"+00:01:42">>])), + ?assertEqual(0, apply_func(FunctionName, [<<"z">>])), + ?assertEqual(0, apply_func(FunctionName, [<<"Z">>])), + ?assertEqual(42, apply_func(FunctionName, [42])), + ?assertEqual(0, apply_func(FunctionName, [undefined])), + %% Check that the following does not crash + apply_func(FunctionName, [<<"local">>]), + apply_func(FunctionName, ["local"]), + apply_func(FunctionName, [local]), + ok. + %%------------------------------------------------------------------------------ %% Utility functions %%------------------------------------------------------------------------------