Skip to content

Commit

Permalink
[New] Add new function to compute difference between to events specif…
Browse files Browse the repository at this point in the history
…ied by xsd:dateTime
  • Loading branch information
rodionnv committed Aug 23, 2023
1 parent e18d712 commit 4c0fd22
Show file tree
Hide file tree
Showing 2 changed files with 112 additions and 0 deletions.
@@ -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;
}

}
@@ -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()
);
}
}

0 comments on commit 4c0fd22

Please sign in to comment.