Open woutslabbinck opened 8 months ago
It can be done with core math:
built-ins like in
@prefix time: <http://www.w3.org/2000/10/swap/time#> .
@prefix math: <http://www.w3.org/2000/10/swap/math#> .
@prefix log: <http://www.w3.org/2000/10/swap/log#> .
@prefix xsd: <http://www.w3.org/2001/XMLSchema#> .
@prefix : <http://example.org/> .
{ ?duration :cronTime ?time } <= {
"" time:localTime ?currentTime . # Current time
(?currentTime ?duration) math:sum ?epoch .
(?lexval xsd:dateTime) log:dtlit ?epoch . # binds ?lexval
(?lexval xsd:dateTime) log:dtlit ?time . # binds ?time
} .
and the query
@prefix xsd: <http://www.w3.org/2001/XMLSchema#> .
@prefix : <http://example.org/> .
{ "P1Y2M3DT10H30M"^^xsd:duration :cronTime ?time } => { "P1Y2M3DT10H30M"^^xsd:duration :cronTime ?time } .
will give
$ eye --quiet --nope cronTime.n3 --query cronTime-query.n3
@prefix xsd: <http://www.w3.org/2001/XMLSchema#>.
@prefix : <http://example.org/>.
"P1Y2M3DT10H30M"^^xsd:duration :cronTime "2024-11-17T03:06:56.306999921Z"^^xsd:dateTime.
That said, there is some danger in doing so as each month (and also each year) is not an equal amount of seconds. This is also why there are 3 duration types.
There is now an extra func:add-duration-to-dateTime
built-in EYE v4.16.2
https://github.com/eyereasoner/eye/commit/ca895f47470229ac0da85dcc6e299e2ee83497d3
This is a small test
$ cat cronTime.n3
@prefix time: <http://www.w3.org/2000/10/swap/time#> .
@prefix func: <http://www.w3.org/2007/rif-builtin-function#> .
@prefix xsd: <http://www.w3.org/2001/XMLSchema#> .
@prefix : <http://example.org/> .
{ ?duration :cronTime ?time } <= {
"" time:localTime ?currentTime . # Current time
(?currentTime ?duration) func:add-duration-to-dateTime ?time . # ?time is the time that the cronJob should fire
} .
$ cat cronTime-query.n3
@prefix xsd: <http://www.w3.org/2001/XMLSchema#> .
@prefix : <http://example.org/> .
{ "P1YT10H30M"^^xsd:duration :cronTime ?time } => { "P1YT10H30M"^^xsd:duration :cronTime ?time } .
{ "P2MT10H30M"^^xsd:duration :cronTime ?time } => { "P2MT10H30M"^^xsd:duration :cronTime ?time } .
{ "P3DT10H30M"^^xsd:duration :cronTime ?time } => { "P3DT10H30M"^^xsd:duration :cronTime ?time } .
{ "P1Y2M3DT10H30M"^^xsd:duration :cronTime ?time } => { "P1Y2M3DT10H30M"^^xsd:duration :cronTime ?time } .
$ eye --quiet --nope cronTime.n3 --query cronTime-query.n3
@prefix xsd: <http://www.w3.org/2001/XMLSchema#>.
@prefix : <http://example.org/>.
"P1YT10H30M"^^xsd:duration :cronTime "2024-09-15T10:28:02Z"^^xsd:dateTime.
"P2MT10H30M"^^xsd:duration :cronTime "2023-11-15T10:28:02Z"^^xsd:dateTime.
"P3DT10H30M"^^xsd:duration :cronTime "2023-09-18T10:28:02Z"^^xsd:dateTime.
"P1Y2M3DT10H30M"^^xsd:duration :cronTime "2024-11-18T10:28:02Z"^^xsd:dateTime.
Wow, nice work. I tested it by also adding the current time and a simple duration:
@prefix time: <http://www.w3.org/2000/10/swap/time#> .
@prefix func: <http://www.w3.org/2007/rif-builtin-function#> .
@prefix xsd: <http://www.w3.org/2001/XMLSchema#> .
@prefix : <http://example.org/> .
{ "P1YT10H30M"^^xsd:duration :cronTime ?time } => { "P1YT10H30M"^^xsd:duration :cronTime ?time } .
{ "P2MT10H30M"^^xsd:duration :cronTime ?time } => { "P2MT10H30M"^^xsd:duration :cronTime ?time } .
{ "P3DT10H30M"^^xsd:duration :cronTime ?time } => { "P3DT10H30M"^^xsd:duration :cronTime ?time } .
{ "P1Y2M3DT10H30M"^^xsd:duration :cronTime ?time } => { "P1Y2M3DT10H30M"^^xsd:duration :cronTime ?time } .
{ "P1Y"^^xsd:duration :cronTime ?time } => { "P1Y"^^xsd:duration :cronTime ?time } .
{ "" time:localTime ?currentTime .} => { :currentTime :is ?currentTime } .
And the output was
@prefix xsd: <http://www.w3.org/2001/XMLSchema#>.
@prefix : <http://example.org/>.
"P1YT10H30M"^^xsd:duration :cronTime "2024-09-15T20:35:20Z"^^xsd:dateTime.
"P2MT10H30M"^^xsd:duration :cronTime "2023-11-15T20:35:20Z"^^xsd:dateTime.
"P3DT10H30M"^^xsd:duration :cronTime "2023-09-18T20:35:20Z"^^xsd:dateTime.
"P1Y2M3DT10H30M"^^xsd:duration :cronTime "2024-11-18T20:35:20Z"^^xsd:dateTime.
"P1Y"^^xsd:duration :cronTime "2024-09-15T10:05:20Z"^^xsd:dateTime.
:currentTime :is "2023-09-15T10:05:10.272Z"^^xsd:dateTime.
So exactly what I had expected.
I'll wait to add this to the code however until eye-js and koreografeye use EYE v4.16.2.
https://github.com/SolidLabResearch/Solid-Agent/blob/09b80a71499eec339aa4ded6306953ab0ec02656/rules/usage-control/CronRule.n3#L60-L63
Following part of the rule uses built-ins to calculate a new time for a duration.
However it fails when the duration contains Months or Years (e.g.
P1Y2M3DT10H30M^^xsd:duration
).This should be fixed such that everything from duration is handled.
Suggestion, this can maybe even make a backward chaining rule to not reproduce it in multiple parts in the codebase?
Pointer: https://eulersharp.sourceforge.net/2003/03swap/eye-builtins.html