Skip to content

Commit

Permalink
Merge pull request #200 from kbss-cvut/issue#31-add-new-function-to-c…
Browse files Browse the repository at this point in the history
…ompute-time-diff

[New] Add new function to compute difference between two xsd:dateTime events
  • Loading branch information
blcham committed Aug 24, 2023
2 parents e18d712 + 836cfb8 commit 4d410e3
Show file tree
Hide file tree
Showing 2 changed files with 101 additions and 0 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
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;

/**
* Computes the time difference between two xsd:dateTime values in milliseconds and returns the result as xsd:long.
* Returns a negative value if the first parameter represents a later time.
*/
public class Duration extends AbstractFunction2 implements ValueFunction {

private static final String TYPE_IRI = KBSS_TIMEF.getURI() + "duration-in-ms";

@Override
public String getTypeURI() {
return TYPE_IRI;
}

@Override
protected NodeValue exec(Node startDateTime, Node endDateTime, FunctionEnv functionEnv) {
Calendar start = parseNodeToCalendar(startDateTime);
Calendar end = parseNodeToCalendar(endDateTime);

long duration = end.getTimeInMillis()-start.getTimeInMillis();
Node node = NodeFactory.createLiteralByValue(duration, XSDDatatype.XSDlong);
return NodeValue.makeNode(node);
}

private Calendar parseNodeToCalendar(Node dateTime){
return DatatypeConverter.parseDateTime(dateTime.getLiteral().getLexicalForm());
}
}
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 startDateTime = getDateTimeNode("2023-08-21T13:00:00.100").asNode();
Node endDateTime = getDateTimeNode("2023-08-21T13:00:00.250").asNode();

NodeValue durationInMS = duration.exec(startDateTime, endDateTime, null);
long expected = 150;
assertEquals(expected,durationInMS.getInteger().intValue());
}

@Test
public void execStartDateTimeIsLaterThenEndDateTime() {

Duration duration = new Duration();
Node startDateTime = getDateTimeNode("2023-08-21T13:20:00").asNode();
Node endDateTime = getDateTimeNode("2023-08-21T13:00:00").asNode();

NodeValue durationInMS = duration.exec(startDateTime, endDateTime,null);
long expected = -1200000;
assertEquals(expected,durationInMS.getInteger().intValue());
}

@Test
public void execTimeZoneFormat() {

Duration duration = new Duration();
Node startDateTime = getDateTimeNode("2023-08-21T15:30:00.100-05:00").asNode();
Node endDateTime = getDateTimeNode("2023-08-21T14:30:05.600-06:00").asNode();

NodeValue durationInMS = duration.exec(startDateTime, endDateTime,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 4d410e3

Please sign in to comment.