Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Proper calulation of datetime of duration #13

Open
woutslabbinck opened this issue Sep 13, 2023 · 4 comments
Open

Proper calulation of datetime of duration #13

woutslabbinck opened this issue Sep 13, 2023 · 4 comments
Assignees

Comments

@woutslabbinck
Copy link
Collaborator

woutslabbinck commented Sep 13, 2023

"" time:localTime ?currentTime . # Current time
(?durationValue ?DType) log:dtlit ?duration .
(?durationValue xsd:dayTimeDuration) log:dtlit ?durationDayTime .
(?currentTime ?durationDayTime) func:add-dayTimeDuration-to-dateTime ?time . # ?time is the time that the cronJob should fire

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

@josd
Copy link

josd commented Sep 14, 2023

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.

@josd
Copy link

josd commented Sep 14, 2023

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.

@josd
Copy link

josd commented Sep 14, 2023

There is now an extra func:add-duration-to-dateTime built-in EYE v4.16.2 eyereasoner/eye@ca895f4
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.

@woutslabbinck
Copy link
Collaborator Author

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.

@woutslabbinck woutslabbinck self-assigned this Sep 15, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants