Commit 638dcebf authored by R.W.Majeed's avatar R.W.Majeed

fixed millisecond precision for date/time handling

parent b5c5f68d
......@@ -37,13 +37,14 @@
<birthdate>2001-01-01</birthdate>
<deathdate>2020</deathdate>
<sex>F</sex>
<encounter start="2014-01-01T10:30:00" end="2014-01-05T10:30:00">XXE12345</encounter>
<encounter start="2014-01-01T10:30:00" end="2014-01-05T10:30:00.123">XXE12345</encounter>
<location>Zuhause</location>
<!-- TODO inpatient/outpatient -->
<provider>xxxa</provider>
<facts>
<!-- test parsing of partial time stamps -->
<eav-item concept="T:date:secs" start="2014-09-07T10:40:03"/>
<eav-item concept="T:date:msec" start="2014-09-07T10:40:03.123"/>
<eav-item concept="T:date:mins" start="2014-09-07T10:40"/>
<eav-item concept="T:date:hours" start="2014-09-07T10"/>
<eav-item concept="T:date:day" start="2014-09-07"/>
......
......@@ -23,9 +23,10 @@ XX12345 XXE12345 gest dat 2020
XX12345 XXE12345 sex str F
XX12345 XXE12345 psurname str Dampf
XX12345 XXE12345 pnames str A B
XX12345 XXE12345 visit @ @ @ 2014-01-01T10:30:00 2014-01-05T10:30:00 xxxa Zuhause
XX12345 XXE12345 visit @ @ @ 2014-01-01T10:30:00 2014-01-05T10:30:00.123 xxxa Zuhause
# normale werte
XX12345 XXE12345 T:date:secs @ @ @ 2014-09-07T10:40:03
XX12345 XXE12345 T:date:msec @ @ @ 2014-09-07T10:40:03.123
XX12345 XXE12345 T:date:mins @ @ @ 2014-09-07T10:40
XX12345 XXE12345 T:date:hours @ @ @ 2014-09-07T10
XX12345 XXE12345 T:date:day @ @ @ 2014-09-07
......
......@@ -201,9 +201,9 @@ public class DateTimeAccuracy implements Comparable<DateTimeAccuracy> {
dt = instant.atOffset(ZoneOffset.UTC).toLocalDateTime();
}
char[] prefixes = {0,'-','-','T',':',':'};
ChronoField[] fields = {ChronoField.YEAR, ChronoField.MONTH_OF_YEAR, ChronoField.DAY_OF_MONTH, ChronoField.HOUR_OF_DAY, ChronoField.MINUTE_OF_HOUR, ChronoField.SECOND_OF_MINUTE};
int[] digits = {4,2,2,2,2,2};
char[] prefixes = {0,'-','-','T',':',':','.'};
ChronoField[] fields = {ChronoField.YEAR, ChronoField.MONTH_OF_YEAR, ChronoField.DAY_OF_MONTH, ChronoField.HOUR_OF_DAY, ChronoField.MINUTE_OF_HOUR, ChronoField.SECOND_OF_MINUTE,ChronoField.MILLI_OF_SECOND};
int[] digits = {4,2,2,2,2,2,3};
int i;
for( i=0; i<fields.length; i++ ){
if( prefixes[i] != 0 )b.append(prefixes[i]);
......@@ -282,7 +282,7 @@ public class DateTimeAccuracy implements Comparable<DateTimeAccuracy> {
// now check for accuracy
ChronoUnit accuracy;
LocalDateTime dateTime;
if( a.isSupported(ChronoField.MILLI_OF_SECOND) ){
if( a.isSupported(ChronoField.NANO_OF_SECOND) ){
// maximum accuracy of nanoseconds
// not supported yet, truncate to seconds
accuracy = ChronoUnit.MILLIS;
......
......@@ -36,6 +36,7 @@ import de.sekmi.histream.Observation;
import de.sekmi.histream.ObservationFactory;
import de.sekmi.histream.ObservationSupplier;
// TODO remove this class
@Deprecated
public class XMLObservationSupplier extends XMLObservationParser implements ObservationSupplier{
//private static final String namespaceURI = "http://sekmi.de/histream/dwh-eav";
......
......@@ -83,7 +83,7 @@ public class TestDateTimeAccuracy {
a = DateTimeAccuracy.parsePartialIso8601("2001-02-03T04:05:06");
assertEquals(ChronoUnit.SECONDS, a.getAccuracy());
a = DateTimeAccuracy.parsePartialIso8601("2001-02-03T04:05:06.789");
assertEquals(ChronoUnit.SECONDS, a.getAccuracy());
assertEquals(ChronoUnit.MILLIS, a.getAccuracy());
// verify zone offset
// for second accuracy
a = DateTimeAccuracy.parsePartialIso8601("2001-02-03T04:05:06+0800");
......@@ -167,6 +167,13 @@ public class TestDateTimeAccuracy {
assertEquals("2001-02-02T20Z", a.toPartialIso8601(ZoneId.of("UTC")));
}
@Test
public void verifyMillisecondParseAndToString() throws ParseException{
DateTimeAccuracy a = DateTimeAccuracy.parsePartialIso8601("2001-02-03T04:05:06.789", ZoneId.of("UTC"));
// date should be treated as if it had a +08:00 offset
assertEquals("2001-02-03T04:05:06.789Z", a.toPartialIso8601(ZoneId.of("UTC")));
}
@Test
public void verifyComparison() throws ParseException{
ZoneId zone = ZoneOffset.UTC.normalized();
......
......@@ -35,9 +35,10 @@ public class ECMAEvaluatorTest {
}
// skip to string value
for( int i=0; i<6; i++ ){
for( int i=0; i<7; i++ ){
o = s.get();
}
Assert.assertEquals("T:type:str", o.getConceptId());
// compare string value
Assert.assertEquals(true, eval.test("fact.value != null", o));
......
......@@ -38,9 +38,10 @@ public class XPathEvaluatorTest {
Assert.assertEquals(expr, true, eval.test(expr, o));
}
// skip to string value
for( int i=0; i<6; i++ ){
for( int i=0; i<7; i++ ){
o = s.get();
}
Assert.assertEquals("T:type:str", o.getConceptId());
// compare string value
Assert.assertEquals(true, eval.test("f:fact/f:value='abc123'", o));
......
......@@ -101,7 +101,7 @@ public class FileObservationProviderTest {
Assert.assertEquals("Zuhause", v.getLocationId());
try{
Assert.assertEquals(DateTimeAccuracy.parsePartialIso8601("2014-01-01T10:30:00"), v.getStartTime());
Assert.assertEquals(DateTimeAccuracy.parsePartialIso8601("2014-01-05T10:30:00"), v.getEndTime());
Assert.assertEquals(DateTimeAccuracy.parsePartialIso8601("2014-01-05T10:30:00.123"), v.getEndTime());
} catch (ParseException e) {
throw new RuntimeException(e);
}
......@@ -114,8 +114,8 @@ public class FileObservationProviderTest {
(Observation o) -> {
Assert.assertEquals("T:date:msec", o.getConceptId());
// TODO store and calculate time in nanos
Assert.assertEquals(ChronoUnit.SECONDS, o.getStartTime().getAccuracy());
Assert.assertEquals(30, o.getStartTime().toInstantMin().atOffset(ZoneOffset.UTC).getLong(ChronoField.MINUTE_OF_HOUR));
Assert.assertEquals(ChronoUnit.MILLIS, o.getStartTime().getAccuracy());
Assert.assertEquals(123, o.getStartTime().toInstantMin().atOffset(ZoneOffset.UTC).getLong(ChronoField.MILLI_OF_SECOND));
},
(Observation o) -> {
Assert.assertEquals("T:date:mins", o.getConceptId());
......@@ -238,6 +238,7 @@ public class FileObservationProviderTest {
@Test
public void testStAXReader() throws FileNotFoundException, XMLStreamException, FactoryConfigurationError {
// TODO delete XMLObservationSupplier
XMLObservationSupplier xos = new XMLObservationSupplier(factory, new FileInputStream("examples/dwh-eav.xml"));
validateExample(xos);
xos.close();
......
......@@ -44,8 +44,8 @@ public class TestExport {
Assert.assertEquals("T:type:str", m.get(MemoryExportWriter.VISIT_TABLE, "byclass", 0));
m.dump();
// verify eav table
Assert.assertEquals(6, m.rowCount("eavtabletest"));
Assert.assertEquals("T:date:month", m.get("eavtabletest", "code", 4));
Assert.assertEquals(7, m.rowCount("eavtabletest"));
Assert.assertEquals("T:date:month", m.get("eavtabletest", "code", 5));
// TODO something wrong with namespaces in xpath/dom
}
......
......@@ -46,7 +46,7 @@ public class TestVisitFragmentParser {
// System.out.println("XPath="+ret);
ret = (String)xp.evaluate("count(eav:fact)", visit, XPathConstants.STRING);
// System.out.println("Facts:"+ret);
Assert.assertEquals("12", ret);
Assert.assertEquals("13", ret);
}
}
......@@ -18,7 +18,7 @@
<dependency>
<groupId>de.sekmi.histream</groupId>
<artifactId>histream-core</artifactId>
<version>0.14-SNAPSHOT</version>
<version>0.16-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>junit</groupId>
......
......@@ -2,6 +2,7 @@ package de.sekmi.histream.scripting;
import java.math.BigDecimal;
import java.text.ParseException;
import java.time.ZoneId;
import de.sekmi.histream.DateTimeAccuracy;
import de.sekmi.histream.Observation;
......@@ -21,11 +22,11 @@ public class Fact {
}
public Fact start(String incompleteDateTime) throws ParseException{
observation.setStartTime(DateTimeAccuracy.parsePartialIso8601(incompleteDateTime));
observation.setStartTime(DateTimeAccuracy.parsePartialIso8601(incompleteDateTime, ZoneId.systemDefault()));
return this;
}
public Fact end(String incompleteDateTime) throws ParseException{
observation.setEndTime(DateTimeAccuracy.parsePartialIso8601(incompleteDateTime));
observation.setEndTime(DateTimeAccuracy.parsePartialIso8601(incompleteDateTime, ZoneId.systemDefault()));
return this;
}
......@@ -58,4 +59,14 @@ public class Fact {
public Observation getObservation(){
return observation;
}
public String toString(){
StringBuilder b = new StringBuilder();
b.append("{patient=").append(getObservation().getPatientId());
b.append(", visit=").append(getObservation().getEncounterId());
b.append(", start=").append(getObservation().getStartTime());
b.append(", concept=").append(getConcept());
b.append("}");
return b.toString();
}
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment