Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
[New] Add new function to compute difference between to events specif…
…ied by xsd:dateTime
- Loading branch information
Showing
2 changed files
with
112 additions
and
0 deletions.
There are no files selected for viewing
52 changes: 52 additions & 0 deletions
52
s-pipes-core/src/main/java/cz/cvut/spipes/function/time/Duration.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,52 @@ | ||
package cz.cvut.spipes.function.time; | ||
|
||
import cz.cvut.spipes.constants.KBSS_TIMEF; | ||
import cz.cvut.spipes.function.ValueFunction; | ||
import org.apache.jena.datatypes.xsd.XSDDatatype; | ||
import org.apache.jena.graph.Node; | ||
import org.apache.jena.graph.NodeFactory; | ||
import org.apache.jena.sparql.expr.NodeValue; | ||
import org.apache.jena.sparql.function.FunctionEnv; | ||
import org.topbraid.spin.arq.AbstractFunction2; | ||
|
||
import javax.xml.bind.DatatypeConverter; | ||
import java.util.Calendar; | ||
import java.util.regex.Matcher; | ||
import java.util.regex.Pattern; | ||
|
||
/** | ||
* Computes difference between two xsd:dateTime values in milliseconds and returns xsd:long datatype | ||
*/ | ||
public class Duration extends AbstractFunction2 implements ValueFunction { | ||
|
||
private static final String TYPE_IRI = KBSS_TIMEF.getURI() + "add-days"; | ||
|
||
@Override | ||
public String getTypeURI() { | ||
return TYPE_IRI; | ||
} | ||
|
||
@Override | ||
protected NodeValue exec(Node t2, Node t1, FunctionEnv functionEnv) { | ||
Calendar start = parseNodeToCalendar(t1); | ||
Calendar end = parseNodeToCalendar(t2); | ||
|
||
long duration = end.getTimeInMillis()-start.getTimeInMillis(); | ||
Node node = NodeFactory.createLiteralByValue(duration, XSDDatatype.XSDlong); | ||
return NodeValue.makeNode(node); | ||
} | ||
|
||
private Calendar parseNodeToCalendar(Node x){ | ||
return DatatypeConverter.parseDateTime(extractDateTimePart(x.getLiteral().toString())); | ||
} | ||
|
||
private static String extractDateTimePart(String rdfLiteral) { | ||
String dateTimePattern = "^(.*?)(?:\\^\\^.*|$)"; | ||
Pattern pattern = Pattern.compile(dateTimePattern); | ||
Matcher matcher = pattern.matcher(rdfLiteral); | ||
|
||
if (matcher.find())return matcher.group(1); | ||
return null; | ||
} | ||
|
||
} |
60 changes: 60 additions & 0 deletions
60
s-pipes-core/src/test/java/cz/cvut/spipes/function/time/DurationTest.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,60 @@ | ||
package cz.cvut.spipes.function.time; | ||
|
||
import org.apache.jena.datatypes.RDFDatatype; | ||
import org.apache.jena.datatypes.xsd.XSDDatatype; | ||
import org.apache.jena.graph.Node; | ||
import org.apache.jena.sparql.expr.NodeValue; | ||
import org.junit.jupiter.api.Test; | ||
|
||
import static org.junit.jupiter.api.Assertions.*; | ||
|
||
class DurationTest { | ||
|
||
@Test | ||
public void execSimple() { | ||
|
||
Duration duration = new Duration(); | ||
Node t1 = getDateTimeNode("2023-08-21T13:00:00.100").asNode(); | ||
Node t2 = getDateTimeNode("2023-08-21T13:00:00.250").asNode(); | ||
|
||
NodeValue durationInMS = duration.exec(t2,t1,null); | ||
long expected = 150; | ||
assertEquals(expected,durationInMS.getInteger().intValue()); | ||
} | ||
|
||
@Test | ||
public void execT2IsEarlierThenT1() { | ||
|
||
Duration duration = new Duration(); | ||
Node t1 = getDateTimeNode("2023-08-21T13:20:00").asNode(); | ||
Node t2 = getDateTimeNode("2023-08-21T13:00:00").asNode(); | ||
|
||
NodeValue durationInMS = duration.exec(t2,t1,null); | ||
long expected = -1200000; | ||
assertEquals(expected,durationInMS.getInteger().intValue()); | ||
} | ||
|
||
@Test | ||
public void execTimeZoneFormat() { | ||
|
||
Duration duration = new Duration(); | ||
Node t1 = getDateTimeNode("2023-08-21T15:30:00.100-05:00").asNode(); | ||
Node t2 = getDateTimeNode("2023-08-21T14:30:05.600-06:00").asNode(); | ||
|
||
NodeValue durationInMS = duration.exec(t2,t1,null); | ||
long expected = 5500; | ||
assertEquals(expected,durationInMS.getInteger().intValue()); | ||
} | ||
|
||
private NodeValue getDateTimeNode(String dateTime){ | ||
return getNode(dateTime, XSDDatatype.XSDdateTime); | ||
} | ||
|
||
private NodeValue getNode(String time, RDFDatatype datatype) { | ||
return NodeValue.makeNode( | ||
time, | ||
null, | ||
datatype.getURI() | ||
); | ||
} | ||
} |