I am very sorry about the late reply.
So the solution I would propose would be to use the JQ plugin. JQ is Java Query, and recently I have found it to be quite useful. You can remove large loops, you can transform data. I believe you could probably remove your python step as well and match all false and False as one like value if you were to perform some trial and error.
The JQ plugin is looking for an object as input. This is going on the assumption that your array you want to loop through is called output_json. If it is not, then you will need to format accordingly. Pass the entire object to the JQ step as input.
This is the JQ statement you will use in the filter section of the plugin input:
def tz_offset(country_code):
if country_code == "US" then -5
elif country_code == "DE" or country_code == "ES" then 1
else 0
end;
def in_working_hours(hour):
hour >= 9 and hour <= 17;
.output_json
| map(
. + {
local_hour: (tz_offset(.country_code) + ((.timestamp + "Z") | fromdateiso8601 | . / 3600 | floor % 24)),
out_of_hours: (
tz_offset(.country_code) + ((.timestamp + "Z") | fromdateiso8601 | . / 3600 | floor % 24) | (. < 9 or . > 17)
)
}
)
I will break each section down so you know what it is doing.
To start I am making the assumption that your time is UTC in your output. You will have to adjust accordingly if that is not accurate.
This function assigns a time zone offset (in hours) based on the country code:
"US"
: UTC-5 (Eastern Time)
"DE"
or "ES"
: UTC+1 (Central European Time)
else 0
: Default for other countries, assumes UTC. :
def tz_offset(country_code):
if country_code == "US" then -5
elif country_code == "DE" or country_code == "ES" then 1
else 0
end;
This function checks whether a given hour is within working hours, I chose 9 to 5 and it is on military time. If working hours are 8AM to 4PM it would be 8 and 16. Adjust to whatever is good for you:
hour >= 9
: Starts at 9 AM.
hour <= 17
: Ends at 5 PM.
Returns true
if the hour is within this range, otherwise false
.
def in_working_hours(hour):
hour >= 9 and hour <= 17;
.output_json
: Accesses the array of objects within the "output_json"
field.
map(...)
: Iterates over each object in the array, applying a transformation to it.
.output_json
| map(...)
This line calculates the local time in the country for each record:
tz_offset(.country_code)
:
- Gets the time zone offset for the
country_code
.
.timestamp + "Z"
:
- Appends
"Z"
to indicate that the timestamp is in UTC format (required by fromdateiso8601
).
fromdateiso8601
:
- Converts the timestamp into a Unix timestamp (seconds since 1970-01-01T00:00:00Z).
. / 3600
:
- Converts Unix timestamp to hours.
floor % 24
:
- Ensures the result is a whole number and wraps it to a 24-hour clock.
tz_offset + ...
:
- Adds the time zone offset to calculate the local hour.
local_hour: (tz_offset(.country_code) + ((.timestamp + "Z") | fromdateiso8601 | . / 3600 | floor % 24))
This calculates the same local_hour
but directly checks if it’s outside working hours:
. < 9
: Before 9 AM.
. > 17
: After 5 PM.
out_of_hours
: true
if the time is outside working hours, false
otherwise.
out_of_hours: (
tz_offset(.country_code) + ((.timestamp + "Z") | fromdateiso8601 | . / 3600 | floor % 24) | (. < 9 or . > 17)
)
The .+
operator adds the new fields (local_hour
and out_of_hours
) to the original object, creating an updated version.
. + { local_hour: ..., out_of_hours: ... }
This was the input I provided:
{"output_json":[{"actor":"xxx","timestamp":"2025-01-14T11:07:24","country_code":"DE"},{"actor":"yyy","timestamp":"2025-01-14T11:07:24","country_code":"ES"},{"actor":"zzz","timestamp":"2025-01-14T11:34:38","country_code":"DE"},{"actor":"aaa","timestamp":"2025-01-14T18:00:00","country_code":"DE"},{"actor":"bbb","timestamp":"2025-01-14T08:30:00","country_code":"ES"},{"actor":"ccc","timestamp":"2025-01-14T16:59:59","country_code":"US"},{"actor":"ddd","timestamp":"2025-01-14T21:00:00","country_code":"US"},{"actor":"eee","timestamp":"2025-01-14T04:00:00","country_code":"DE"},{"actor":"fff","timestamp":"2025-01-14T14:00:00","country_code":"ES"},{"actor":"ggg","timestamp":"2025-01-14T06:00:00","country_code":"US"}]}
This was the output received:
[ { "actor": "xxx", "country_code": "DE", "timestamp": "2025-01-14T11:07:24", "local_hour": 12, "out_of_hours": false }, { "actor": "yyy", "country_code": "ES", "timestamp": "2025-01-14T11:07:24", "local_hour": 12, "out_of_hours": false }, { "actor": "zzz", "country_code": "DE", "timestamp": "2025-01-14T11:34:38", "local_hour": 12, "out_of_hours": false }, { "actor": "aaa", "country_code": "DE", "timestamp": "2025-01-14T18:00:00", "local_hour": 19, "out_of_hours": true }, { "actor": "bbb", "country_code": "ES", "timestamp": "2025-01-14T08:30:00", "local_hour": 9, "out_of_hours": false }, { "actor": "ccc", "country_code": "US", "timestamp": "2025-01-14T16:59:59", "local_hour": 11, "out_of_hours": false }, { "actor": "ddd", "country_code": "US", "timestamp": "2025-01-14T21:00:00", "local_hour": 16, "out_of_hours": false }, { "actor": "eee", "country_code": "DE", "timestamp": "2025-01-14T04:00:00", "local_hour": 5, "out_of_hours": true }, { "actor": "fff", "country_code": "ES", "timestamp": "2025-01-14T14:00:00", "local_hour": 15, "out_of_hours": false }, { "actor": "ggg", "country_code": "US", "timestamp": "2025-01-14T06:00:00", "local_hour": 1, "out_of_hours": true } ]
I hope this helps get you started.