Merge branch 'master' of github.com:jamesagnew/hapi-fhir
This commit is contained in:
commit
eae96983e8
|
@ -35,6 +35,7 @@ import java.util.List;
|
|||
import java.util.TimeZone;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
import org.apache.commons.lang3.BooleanUtils;
|
||||
import org.apache.commons.lang3.Validate;
|
||||
import org.apache.commons.lang3.time.DateUtils;
|
||||
import org.apache.commons.lang3.time.FastDateFormat;
|
||||
|
@ -202,7 +203,8 @@ public abstract class BaseDateTimeDt extends BasePrimitive<Date> {
|
|||
}
|
||||
|
||||
/**
|
||||
* Returns the TimeZone associated with this dateTime's value. May return <code>null</code> if no timezone was supplied.
|
||||
* Returns the TimeZone associated with this dateTime's value. May return <code>null</code> if no timezone was
|
||||
* supplied.
|
||||
*/
|
||||
public TimeZone getTimeZone() {
|
||||
return myTimeZone;
|
||||
|
@ -304,18 +306,30 @@ public abstract class BaseDateTimeDt extends BasePrimitive<Date> {
|
|||
|
||||
Date retVal;
|
||||
if (hasMillis) {
|
||||
String value = theValue;
|
||||
|
||||
/*
|
||||
* If we have more than 3 digits of precision after the decimal point, we
|
||||
* only parse the first 3 since Java Dates don't support more than that and
|
||||
* FastDateFormat gets confused
|
||||
*/
|
||||
int offsetIndex = getOffsetIndex(theValue);
|
||||
if (offsetIndex >= 24) {
|
||||
value = theValue.substring(0, 23) + theValue.substring(offsetIndex);
|
||||
}
|
||||
|
||||
try {
|
||||
if (hasOffset(theValue)) {
|
||||
retVal = ourYearMonthDayTimeMilliZoneFormat.parse(theValue);
|
||||
} else if (theValue.endsWith("Z")) {
|
||||
retVal = ourYearMonthDayTimeMilliUTCZFormat.parse(theValue);
|
||||
if (hasOffset(value)) {
|
||||
retVal = ourYearMonthDayTimeMilliZoneFormat.parse(value);
|
||||
} else if (value.endsWith("Z")) {
|
||||
retVal = ourYearMonthDayTimeMilliUTCZFormat.parse(value);
|
||||
} else {
|
||||
retVal = ourYearMonthDayTimeMilliFormat.parse(theValue);
|
||||
retVal = ourYearMonthDayTimeMilliFormat.parse(value);
|
||||
}
|
||||
} catch (ParseException p2) {
|
||||
throw new DataFormatException("Invalid data/time string (" + p2.getMessage() + "): " + theValue);
|
||||
}
|
||||
setTimeZone(theValue, hasMillis);
|
||||
setTimeZone(theValue);
|
||||
setPrecision(TemporalPrecisionEnum.MILLI);
|
||||
} else {
|
||||
try {
|
||||
|
@ -330,7 +344,7 @@ public abstract class BaseDateTimeDt extends BasePrimitive<Date> {
|
|||
throw new DataFormatException("Invalid data/time string (" + p2.getMessage() + "): " + theValue);
|
||||
}
|
||||
|
||||
setTimeZone(theValue, hasMillis);
|
||||
setTimeZone(theValue);
|
||||
setPrecision(TemporalPrecisionEnum.SECOND);
|
||||
}
|
||||
|
||||
|
@ -356,18 +370,34 @@ public abstract class BaseDateTimeDt extends BasePrimitive<Date> {
|
|||
updateStringValue();
|
||||
}
|
||||
|
||||
private BaseDateTimeDt setTimeZone(String theValueString, boolean hasMillis) {
|
||||
clearTimeZone();
|
||||
int timeZoneStart = 19;
|
||||
if (hasMillis)
|
||||
timeZoneStart += 4;
|
||||
if (theValueString.endsWith("Z")) {
|
||||
setTimeZoneZulu(true);
|
||||
} else if (theValueString.indexOf("GMT", timeZoneStart) != -1) {
|
||||
setTimeZone(TimeZone.getTimeZone(theValueString.substring(timeZoneStart)));
|
||||
} else if (theValueString.indexOf('+', timeZoneStart) != -1 || theValueString.indexOf('-', timeZoneStart) != -1) {
|
||||
setTimeZone(TimeZone.getTimeZone("GMT" + theValueString.substring(timeZoneStart)));
|
||||
private int getOffsetIndex(String theValueString) {
|
||||
int plusIndex = theValueString.indexOf('+', 19);
|
||||
int minusIndex = theValueString.indexOf('-', 19);
|
||||
int zIndex = theValueString.indexOf('Z', 19);
|
||||
int retVal = Math.max(Math.max(plusIndex, minusIndex), zIndex);
|
||||
if (retVal == -1) {
|
||||
return -1;
|
||||
}
|
||||
if ((retVal - 2) != (plusIndex + minusIndex + zIndex)) {
|
||||
// This means we have more than one separator
|
||||
throw new DataFormatException("Invalid FHIR date/time string: " + theValueString);
|
||||
}
|
||||
return retVal;
|
||||
}
|
||||
|
||||
private BaseDateTimeDt setTimeZone(String theValueString) {
|
||||
clearTimeZone();
|
||||
|
||||
int sepIndex = getOffsetIndex(theValueString);
|
||||
if (sepIndex != -1) {
|
||||
if (theValueString.charAt(sepIndex) == 'Z') {
|
||||
setTimeZoneZulu(true);
|
||||
} else {
|
||||
String offsetString = theValueString.substring(sepIndex);
|
||||
setTimeZone(TimeZone.getTimeZone("GMT" + offsetString));
|
||||
}
|
||||
}
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
|
@ -384,7 +414,8 @@ public abstract class BaseDateTimeDt extends BasePrimitive<Date> {
|
|||
}
|
||||
|
||||
/**
|
||||
* Sets the value for this type using the given Java Date object as the time, and using the default precision for this datatype, as well as the local timezone as determined by the local operating
|
||||
* Sets the value for this type using the given Java Date object as the time, and using the default precision for
|
||||
* this datatype, as well as the local timezone as determined by the local operating
|
||||
* system. Both of these properties may be modified in subsequent calls if neccesary.
|
||||
*/
|
||||
@Override
|
||||
|
@ -394,7 +425,8 @@ public abstract class BaseDateTimeDt extends BasePrimitive<Date> {
|
|||
}
|
||||
|
||||
/**
|
||||
* Sets the value for this type using the given Java Date object as the time, and using the specified precision, as well as the local timezone as determined by the local operating system. Both of
|
||||
* Sets the value for this type using the given Java Date object as the time, and using the specified precision, as
|
||||
* well as the local timezone as determined by the local operating system. Both of
|
||||
* these properties may be modified in subsequent calls if neccesary.
|
||||
*
|
||||
* @param theValue
|
||||
|
@ -418,8 +450,10 @@ public abstract class BaseDateTimeDt extends BasePrimitive<Date> {
|
|||
/**
|
||||
* Returns a human readable version of this date/time using the system local format.
|
||||
* <p>
|
||||
* <b>Note on time zones:</b> This method renders the value using the time zone that is contained within the value. For example, if this date object contains the value "2012-01-05T12:00:00-08:00",
|
||||
* the human display will be rendered as "12:00:00" even if the application is being executed on a system in a different time zone. If this behaviour is not what you want, use
|
||||
* <b>Note on time zones:</b> This method renders the value using the time zone that is contained within the value.
|
||||
* For example, if this date object contains the value "2012-01-05T12:00:00-08:00",
|
||||
* the human display will be rendered as "12:00:00" even if the application is being executed on a system in a
|
||||
* different time zone. If this behaviour is not what you want, use
|
||||
* {@link #toHumanDisplayLocalTimezone()} instead.
|
||||
* </p>
|
||||
*/
|
||||
|
@ -441,7 +475,8 @@ public abstract class BaseDateTimeDt extends BasePrimitive<Date> {
|
|||
}
|
||||
|
||||
/**
|
||||
* Returns a human readable version of this date/time using the system local format, converted to the local timezone if neccesary.
|
||||
* Returns a human readable version of this date/time using the system local format, converted to the local timezone
|
||||
* if neccesary.
|
||||
*
|
||||
* @see #toHumanDisplay() for a method which does not convert the time to the local timezone before rendering it.
|
||||
*/
|
||||
|
|
|
@ -0,0 +1,20 @@
|
|||
package ca.uhn.fhir.jpa.z;
|
||||
|
||||
import org.junit.Test;
|
||||
import org.springframework.test.annotation.DirtiesContext;
|
||||
|
||||
import ca.uhn.fhir.jpa.dao.dstu2.BaseJpaDstu2Test;
|
||||
|
||||
public class ZContextCloserDstu2Test extends BaseJpaDstu2Test {
|
||||
|
||||
/**
|
||||
* this is just here to close the context when this package's test are done
|
||||
*/
|
||||
@Test
|
||||
@DirtiesContext()
|
||||
public void testCloseContext() {
|
||||
// nothing
|
||||
}
|
||||
|
||||
|
||||
}
|
|
@ -0,0 +1,20 @@
|
|||
package ca.uhn.fhir.jpa.z;
|
||||
|
||||
import org.junit.Test;
|
||||
import org.springframework.test.annotation.DirtiesContext;
|
||||
|
||||
import ca.uhn.fhir.jpa.dao.dstu3.BaseJpaDstu3Test;
|
||||
|
||||
public class ZContextCloserDstu3Test extends BaseJpaDstu3Test {
|
||||
|
||||
/**
|
||||
* this is just here to close the context when this package's test are done
|
||||
*/
|
||||
@Test
|
||||
@DirtiesContext()
|
||||
public void testCloseContext() {
|
||||
// nothing
|
||||
}
|
||||
|
||||
|
||||
}
|
|
@ -124,7 +124,7 @@ public class TestRestfulServer extends RestfulServer {
|
|||
myAppCtx = new AnnotationConfigWebApplicationContext();
|
||||
myAppCtx.setServletConfig(getServletConfig());
|
||||
myAppCtx.setParent(parentAppCtx);
|
||||
if ("TDL2".equals(fhirVersionParam.trim().toUpperCase())) {
|
||||
if ("TDL3".equals(fhirVersionParam.trim().toUpperCase())) {
|
||||
myAppCtx.register(TdlDstu3Config.class);
|
||||
baseUrlProperty = FHIR_BASEURL_TDL3;
|
||||
} else {
|
||||
|
|
|
@ -17,6 +17,7 @@ import org.junit.BeforeClass;
|
|||
import org.junit.Test;
|
||||
|
||||
import ca.uhn.fhir.model.api.TemporalPrecisionEnum;
|
||||
import ca.uhn.fhir.parser.DataFormatException;
|
||||
import ca.uhn.fhir.util.TestUtil;
|
||||
|
||||
public class BaseDateTimeDtDstu2Test {
|
||||
|
@ -53,6 +54,106 @@ public class BaseDateTimeDtDstu2Test {
|
|||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testParseTimeZoneOffsetCorrectly0millis() {
|
||||
myDateInstantParser.setTimeZone(TimeZone.getTimeZone("America/Toronto"));
|
||||
|
||||
DateTimeDt dt = new DateTimeDt("2010-01-01T00:00:00-09:00");
|
||||
|
||||
assertEquals("2010-01-01T00:00:00-09:00", dt.getValueAsString());
|
||||
assertEquals("2010-01-01 04:00:00.000", myDateInstantParser.format(dt.getValue()));
|
||||
assertEquals("GMT-09:00", dt.getTimeZone().getID());
|
||||
assertEquals(-32400000L, dt.getTimeZone().getRawOffset());
|
||||
|
||||
dt.setTimeZoneZulu(true);
|
||||
assertEquals("2010-01-01T09:00:00Z", dt.getValueAsString());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testParseTimeZoneOffsetCorrectly1millis() {
|
||||
myDateInstantParser.setTimeZone(TimeZone.getTimeZone("America/Toronto"));
|
||||
|
||||
DateTimeDt dt = new DateTimeDt("2010-01-01T00:00:00.1-09:00");
|
||||
|
||||
assertEquals("2010-01-01T00:00:00.1-09:00", dt.getValueAsString());
|
||||
assertEquals("2010-01-01 04:00:00.001", myDateInstantParser.format(dt.getValue()));
|
||||
assertEquals("GMT-09:00", dt.getTimeZone().getID());
|
||||
assertEquals(-32400000L, dt.getTimeZone().getRawOffset());
|
||||
|
||||
dt.setTimeZoneZulu(true);
|
||||
assertEquals("2010-01-01T09:00:00.001Z", dt.getValueAsString());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testParseTimeZoneOffsetCorrectly2millis() {
|
||||
myDateInstantParser.setTimeZone(TimeZone.getTimeZone("America/Toronto"));
|
||||
|
||||
DateTimeDt dt = new DateTimeDt("2010-01-01T00:00:00.12-09:00");
|
||||
|
||||
assertEquals("2010-01-01T00:00:00.12-09:00", dt.getValueAsString());
|
||||
assertEquals("2010-01-01 04:00:00.012", myDateInstantParser.format(dt.getValue()));
|
||||
assertEquals("GMT-09:00", dt.getTimeZone().getID());
|
||||
assertEquals(-32400000L, dt.getTimeZone().getRawOffset());
|
||||
|
||||
dt.setTimeZoneZulu(true);
|
||||
assertEquals("2010-01-01T09:00:00.012Z", dt.getValueAsString());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testParseTimeZoneOffsetCorrectly3millis() {
|
||||
myDateInstantParser.setTimeZone(TimeZone.getTimeZone("America/Toronto"));
|
||||
|
||||
DateTimeDt dt = new DateTimeDt("2010-01-01T00:00:00.123-09:00");
|
||||
|
||||
assertEquals("2010-01-01T00:00:00.123-09:00", dt.getValueAsString());
|
||||
assertEquals("2010-01-01 04:00:00.123", myDateInstantParser.format(dt.getValue()));
|
||||
assertEquals("GMT-09:00", dt.getTimeZone().getID());
|
||||
assertEquals(-32400000L, dt.getTimeZone().getRawOffset());
|
||||
|
||||
dt.setTimeZoneZulu(true);
|
||||
assertEquals("2010-01-01T09:00:00.123Z", dt.getValueAsString());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testParseInvalidZoneOffset() {
|
||||
try {
|
||||
new DateTimeDt("2010-01-01T00:00:00.1234-09:00Z");
|
||||
fail();
|
||||
} catch (DataFormatException e) {
|
||||
assertEquals("Invalid FHIR date/time string: 2010-01-01T00:00:00.1234-09:00Z", e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testParseTimeZoneOffsetCorrectly4millis() {
|
||||
myDateInstantParser.setTimeZone(TimeZone.getTimeZone("America/Toronto"));
|
||||
|
||||
DateTimeDt dt = new DateTimeDt("2010-01-01T00:00:00.1234-09:00");
|
||||
|
||||
assertEquals("2010-01-01T00:00:00.1234-09:00", dt.getValueAsString());
|
||||
assertEquals("2010-01-01 04:00:00.123", myDateInstantParser.format(dt.getValue()));
|
||||
assertEquals("GMT-09:00", dt.getTimeZone().getID());
|
||||
assertEquals(-32400000L, dt.getTimeZone().getRawOffset());
|
||||
|
||||
dt.setTimeZoneZulu(true);
|
||||
assertEquals("2010-01-01T09:00:00.123Z", dt.getValueAsString());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testParseTimeZoneOffsetCorrectly5millis() {
|
||||
myDateInstantParser.setTimeZone(TimeZone.getTimeZone("America/Toronto"));
|
||||
|
||||
DateTimeDt dt = new DateTimeDt("2010-01-01T00:00:00.12345-09:00");
|
||||
|
||||
assertEquals("2010-01-01T00:00:00.12345-09:00", dt.getValueAsString());
|
||||
assertEquals("2010-01-01 04:00:00.123", myDateInstantParser.format(dt.getValue()));
|
||||
assertEquals("GMT-09:00", dt.getTimeZone().getID());
|
||||
assertEquals(-32400000L, dt.getTimeZone().getRawOffset());
|
||||
|
||||
dt.setTimeZoneZulu(true);
|
||||
assertEquals("2010-01-01T09:00:00.123Z", dt.getValueAsString());
|
||||
}
|
||||
|
||||
/**
|
||||
* See HAPI #101 - https://github.com/jamesagnew/hapi-fhir/issues/101
|
||||
*/
|
||||
|
|
|
@ -104,7 +104,7 @@ public class ETagServerTest {
|
|||
|
||||
@Test
|
||||
public void testLastModifiedHeader() throws Exception {
|
||||
ourLastModifiedDate = new InstantDt("2012-11-25T02:34:45.2222Z").getValue();
|
||||
ourLastModifiedDate = new InstantDt("2012-11-25T02:34:45.222Z").getValue();
|
||||
|
||||
HttpGet httpGet = new HttpGet("http://localhost:" + ourPort + "/Patient/2/_history/3");
|
||||
HttpResponse status = ourClient.execute(httpGet);
|
||||
|
@ -118,7 +118,7 @@ public class ETagServerTest {
|
|||
|
||||
Header cl = status.getFirstHeader(Constants.HEADER_LAST_MODIFIED_LOWERCASE);
|
||||
assertNotNull(cl);
|
||||
assertEquals("Sun, 25 Nov 2012 02:34:47 GMT", cl.getValue());
|
||||
assertEquals("Sun, 25 Nov 2012 02:34:45 GMT", cl.getValue());
|
||||
} finally {
|
||||
if (status.getEntity() != null) {
|
||||
IOUtils.closeQuietly(status.getEntity().getContent());
|
||||
|
|
|
@ -19,6 +19,7 @@ import org.apache.commons.lang3.Validate;
|
|||
import org.apache.commons.lang3.time.DateUtils;
|
||||
import org.apache.commons.lang3.time.FastDateFormat;
|
||||
|
||||
import ca.uhn.fhir.model.primitive.BaseDateTimeDt;
|
||||
import ca.uhn.fhir.parser.DataFormatException;
|
||||
|
||||
public abstract class BaseDateTimeType extends PrimitiveType<Date> {
|
||||
|
@ -332,12 +333,12 @@ public abstract class BaseDateTimeType extends PrimitiveType<Date> {
|
|||
} else if (theValue.length() >= 16) { // date and time with possible time zone
|
||||
char timeSeparator = theValue.charAt(10);
|
||||
if (timeSeparator != 'T') {
|
||||
throw new DataFormatException("Invalid date/time string: " + theValue);
|
||||
throw new DataFormatException("Invalid date/time string (invalid length): " + theValue);
|
||||
}
|
||||
|
||||
int firstColonIndex = theValue.indexOf(':');
|
||||
if (firstColonIndex == -1) {
|
||||
throw new DataFormatException("Invalid date/time string: " + theValue);
|
||||
throw new DataFormatException("Invalid date/time string (invalid length): " + theValue);
|
||||
}
|
||||
|
||||
boolean hasSeconds = theValue.length() > firstColonIndex+3 ? theValue.charAt(firstColonIndex+3) == ':' : false;
|
||||
|
@ -355,18 +356,30 @@ public abstract class BaseDateTimeType extends PrimitiveType<Date> {
|
|||
|
||||
Date retVal;
|
||||
if (hasMillis) {
|
||||
|
||||
/*
|
||||
* If we have more than 3 digits of precision after the decimal point, we
|
||||
* only parse the first 3 since Java Dates don't support more than that and
|
||||
* FastDateFormat gets confused
|
||||
*/
|
||||
String value = theValue;
|
||||
int offsetIndex = getOffsetIndex(theValue);
|
||||
if (offsetIndex >= 24) {
|
||||
value = theValue.substring(0, 23) + theValue.substring(offsetIndex);
|
||||
}
|
||||
|
||||
try {
|
||||
if (hasOffset(theValue)) {
|
||||
retVal = ourYearMonthDayTimeMilliZoneFormat.parse(theValue);
|
||||
} else if (theValue.endsWith("Z")) {
|
||||
retVal = ourYearMonthDayTimeMilliUTCZFormat.parse(theValue);
|
||||
if (hasOffset(value)) {
|
||||
retVal = ourYearMonthDayTimeMilliZoneFormat.parse(value);
|
||||
} else if (value.endsWith("Z")) {
|
||||
retVal = ourYearMonthDayTimeMilliUTCZFormat.parse(value);
|
||||
} else {
|
||||
retVal = ourYearMonthDayTimeMilliFormat.parse(theValue);
|
||||
retVal = ourYearMonthDayTimeMilliFormat.parse(value);
|
||||
}
|
||||
} catch (ParseException p2) {
|
||||
throw new DataFormatException("Invalid data/time string (" + p2.getMessage() + "): " + theValue);
|
||||
}
|
||||
setTimeZone(theValue, hasMillis);
|
||||
setTimeZone(theValue);
|
||||
setPrecision(TemporalPrecisionEnum.MILLI);
|
||||
} else if (hasSeconds) {
|
||||
try {
|
||||
|
@ -381,7 +394,7 @@ public abstract class BaseDateTimeType extends PrimitiveType<Date> {
|
|||
throw new DataFormatException("Invalid data/time string (" + p2.getMessage() + "): " + theValue);
|
||||
}
|
||||
|
||||
setTimeZone(theValue, hasMillis);
|
||||
setTimeZone(theValue);
|
||||
setPrecision(TemporalPrecisionEnum.SECOND);
|
||||
} else {
|
||||
try {
|
||||
|
@ -396,7 +409,7 @@ public abstract class BaseDateTimeType extends PrimitiveType<Date> {
|
|||
throw new DataFormatException("Invalid data/time string (" + p2.getMessage() + "): " + theValue, p2);
|
||||
}
|
||||
|
||||
setTimeZone(theValue, hasMillis);
|
||||
setTimeZone(theValue);
|
||||
setPrecision(TemporalPrecisionEnum.MINUTE);
|
||||
}
|
||||
|
||||
|
@ -444,18 +457,35 @@ public abstract class BaseDateTimeType extends PrimitiveType<Date> {
|
|||
updateStringValue();
|
||||
}
|
||||
|
||||
private void setTimeZone(String theValueString, boolean hasMillis) {
|
||||
clearTimeZone();
|
||||
int timeZoneStart = 19;
|
||||
if (hasMillis)
|
||||
timeZoneStart += 4;
|
||||
if (theValueString.endsWith("Z")) {
|
||||
setTimeZoneZulu(true);
|
||||
} else if (theValueString.indexOf("GMT", timeZoneStart) != -1) {
|
||||
setTimeZone(TimeZone.getTimeZone(theValueString.substring(timeZoneStart)));
|
||||
} else if (theValueString.indexOf('+', timeZoneStart) != -1 || theValueString.indexOf('-', timeZoneStart) != -1) {
|
||||
setTimeZone(TimeZone.getTimeZone("GMT" + theValueString.substring(timeZoneStart)));
|
||||
private int getOffsetIndex(String theValueString) {
|
||||
int plusIndex = theValueString.indexOf('+', 19);
|
||||
int minusIndex = theValueString.indexOf('-', 19);
|
||||
int zIndex = theValueString.indexOf('Z');
|
||||
int retVal = Math.max(Math.max(plusIndex, minusIndex), zIndex);
|
||||
if (retVal == -1) {
|
||||
return -1;
|
||||
}
|
||||
if ((retVal - 2) != (plusIndex + minusIndex + zIndex)) {
|
||||
// This means we have more than one separator
|
||||
throw new DataFormatException("Invalid FHIR date/time string: " + theValueString);
|
||||
}
|
||||
return retVal;
|
||||
}
|
||||
|
||||
private BaseDateTimeType setTimeZone(String theValueString) {
|
||||
clearTimeZone();
|
||||
|
||||
int sepIndex = getOffsetIndex(theValueString);
|
||||
if (sepIndex != -1) {
|
||||
if (theValueString.charAt(sepIndex) == 'Z') {
|
||||
setTimeZoneZulu(true);
|
||||
} else {
|
||||
String offsetString = theValueString.substring(sepIndex);
|
||||
setTimeZone(TimeZone.getTimeZone("GMT" + offsetString));
|
||||
}
|
||||
}
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
public void setTimeZone(TimeZone theTimeZone) {
|
||||
|
|
|
@ -332,6 +332,30 @@ public class FhirInstanceValidatorDstu3Test {
|
|||
assertEquals(output.toString(), 0, output.getMessages().size());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testValidateRawXmlWithMissingRootNamespace() {
|
||||
//@formatter:off
|
||||
String input = ""
|
||||
+ "<Patient>"
|
||||
+ " <text>"
|
||||
+ " <status value=\"generated\"/>"
|
||||
+ " <div xmlns=\"http://www.w3.org/1999/xhtml\">Some narrative</div>"
|
||||
+ " </text>"
|
||||
+ " <name>"
|
||||
+ " <use value=\"official\"/>"
|
||||
+ " <family value=\"Doe\"/>"
|
||||
+ " <given value=\"John\"/>"
|
||||
+ " </name>"
|
||||
+ " <gender value=\"male\"/>"
|
||||
+ " <birthDate value=\"1974-12-25\"/>"
|
||||
+ "</Patient>";
|
||||
//@formatter:on
|
||||
|
||||
ValidationResult output = myVal.validateWithResult(input);
|
||||
assertEquals(output.toString(), 1, output.getMessages().size());
|
||||
ourLog.info(output.getMessages().get(0).getLocationString());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testValidateRawJsonResourceBadAttributes() {
|
||||
//@formatter:off
|
||||
|
|
|
@ -0,0 +1,231 @@
|
|||
package org.hl7.fhir.dstu3.model;
|
||||
|
||||
import static org.hamcrest.Matchers.containsString;
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertThat;
|
||||
import static org.junit.Assert.fail;
|
||||
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.Calendar;
|
||||
import java.util.Date;
|
||||
import java.util.Locale;
|
||||
import java.util.TimeZone;
|
||||
|
||||
import org.junit.AfterClass;
|
||||
import org.junit.Before;
|
||||
import org.junit.BeforeClass;
|
||||
import org.junit.Test;
|
||||
|
||||
import ca.uhn.fhir.parser.DataFormatException;
|
||||
import ca.uhn.fhir.util.TestUtil;
|
||||
|
||||
public class BaseDateTimeTypeDstu3Test {
|
||||
private static Locale ourDefaultLocale;
|
||||
private static final org.slf4j.Logger ourLog = org.slf4j.LoggerFactory.getLogger(BaseDateTimeTypeDstu3Test.class);
|
||||
private SimpleDateFormat myDateInstantParser;
|
||||
|
||||
@AfterClass
|
||||
public static void afterClassClearContext() {
|
||||
TestUtil.clearAllStaticFieldsForUnitTest();
|
||||
}
|
||||
|
||||
|
||||
@Before
|
||||
public void before() {
|
||||
myDateInstantParser = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testParseInvalidZoneOffset() {
|
||||
try {
|
||||
new DateTimeType("2010-01-01T00:00:00.1234-09:00Z");
|
||||
fail();
|
||||
} catch (DataFormatException e) {
|
||||
assertEquals("Invalid FHIR date/time string: 2010-01-01T00:00:00.1234-09:00Z", e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testParseInvalid() {
|
||||
try {
|
||||
DateTimeType dt = new DateTimeType();
|
||||
dt.setValueAsString("1974-12-25+10:00");
|
||||
fail();
|
||||
} catch (ca.uhn.fhir.parser.DataFormatException e) {
|
||||
assertEquals("Invalid date/time string (invalid length): 1974-12-25+10:00", e.getMessage());
|
||||
}
|
||||
try {
|
||||
DateTimeType dt = new DateTimeType();
|
||||
dt.setValueAsString("1974-12-25Z");
|
||||
fail();
|
||||
} catch (ca.uhn.fhir.parser.DataFormatException e) {
|
||||
assertEquals("Invalid date/time string (invalid length): 1974-12-25Z", e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testParseTimeZoneOffsetCorrectly0millis() {
|
||||
myDateInstantParser.setTimeZone(TimeZone.getTimeZone("America/Toronto"));
|
||||
|
||||
DateTimeType dt = new DateTimeType("2010-01-01T00:00:00-09:00");
|
||||
|
||||
assertEquals("2010-01-01T00:00:00-09:00", dt.getValueAsString());
|
||||
assertEquals("2010-01-01 04:00:00.000", myDateInstantParser.format(dt.getValue()));
|
||||
assertEquals("GMT-09:00", dt.getTimeZone().getID());
|
||||
assertEquals(-32400000L, dt.getTimeZone().getRawOffset());
|
||||
|
||||
dt.setTimeZoneZulu(true);
|
||||
assertEquals("2010-01-01T09:00:00Z", dt.getValueAsString());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testParseTimeZoneOffsetCorrectly1millis() {
|
||||
myDateInstantParser.setTimeZone(TimeZone.getTimeZone("America/Toronto"));
|
||||
|
||||
DateTimeType dt = new DateTimeType("2010-01-01T00:00:00.1-09:00");
|
||||
|
||||
assertEquals("2010-01-01T00:00:00.1-09:00", dt.getValueAsString());
|
||||
assertEquals("2010-01-01 04:00:00.001", myDateInstantParser.format(dt.getValue()));
|
||||
assertEquals("GMT-09:00", dt.getTimeZone().getID());
|
||||
assertEquals(-32400000L, dt.getTimeZone().getRawOffset());
|
||||
|
||||
dt.setTimeZoneZulu(true);
|
||||
assertEquals("2010-01-01T09:00:00.001Z", dt.getValueAsString());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testParseTimeZoneOffsetCorrectly2millis() {
|
||||
myDateInstantParser.setTimeZone(TimeZone.getTimeZone("America/Toronto"));
|
||||
|
||||
DateTimeType dt = new DateTimeType("2010-01-01T00:00:00.12-09:00");
|
||||
|
||||
assertEquals("2010-01-01T00:00:00.12-09:00", dt.getValueAsString());
|
||||
assertEquals("2010-01-01 04:00:00.012", myDateInstantParser.format(dt.getValue()));
|
||||
assertEquals("GMT-09:00", dt.getTimeZone().getID());
|
||||
assertEquals(-32400000L, dt.getTimeZone().getRawOffset());
|
||||
|
||||
dt.setTimeZoneZulu(true);
|
||||
assertEquals("2010-01-01T09:00:00.012Z", dt.getValueAsString());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testParseTimeZoneOffsetCorrectly3millis() {
|
||||
myDateInstantParser.setTimeZone(TimeZone.getTimeZone("America/Toronto"));
|
||||
|
||||
DateTimeType dt = new DateTimeType("2010-01-01T00:00:00.123-09:00");
|
||||
|
||||
assertEquals("2010-01-01T00:00:00.123-09:00", dt.getValueAsString());
|
||||
assertEquals("2010-01-01 04:00:00.123", myDateInstantParser.format(dt.getValue()));
|
||||
assertEquals("GMT-09:00", dt.getTimeZone().getID());
|
||||
assertEquals(-32400000L, dt.getTimeZone().getRawOffset());
|
||||
|
||||
dt.setTimeZoneZulu(true);
|
||||
assertEquals("2010-01-01T09:00:00.123Z", dt.getValueAsString());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testParseTimeZoneOffsetCorrectly4millis() {
|
||||
myDateInstantParser.setTimeZone(TimeZone.getTimeZone("America/Toronto"));
|
||||
|
||||
DateTimeType dt = new DateTimeType("2010-01-01T00:00:00.1234-09:00");
|
||||
|
||||
assertEquals("2010-01-01T00:00:00.1234-09:00", dt.getValueAsString());
|
||||
assertEquals("2010-01-01 04:00:00.123", myDateInstantParser.format(dt.getValue()));
|
||||
assertEquals("GMT-09:00", dt.getTimeZone().getID());
|
||||
assertEquals(-32400000L, dt.getTimeZone().getRawOffset());
|
||||
|
||||
dt.setTimeZoneZulu(true);
|
||||
assertEquals("2010-01-01T09:00:00.123Z", dt.getValueAsString());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testParseTimeZoneOffsetCorrectly5millis() {
|
||||
myDateInstantParser.setTimeZone(TimeZone.getTimeZone("America/Toronto"));
|
||||
|
||||
DateTimeType dt = new DateTimeType("2010-01-01T00:00:00.12345-09:00");
|
||||
|
||||
assertEquals("2010-01-01T00:00:00.12345-09:00", dt.getValueAsString());
|
||||
assertEquals("2010-01-01 04:00:00.123", myDateInstantParser.format(dt.getValue()));
|
||||
assertEquals("GMT-09:00", dt.getTimeZone().getID());
|
||||
assertEquals(-32400000L, dt.getTimeZone().getRawOffset());
|
||||
|
||||
dt.setTimeZoneZulu(true);
|
||||
assertEquals("2010-01-01T09:00:00.123Z", dt.getValueAsString());
|
||||
}
|
||||
|
||||
/**
|
||||
* See HAPI #101 - https://github.com/jamesagnew/hapi-fhir/issues/101
|
||||
*/
|
||||
@Test
|
||||
public void testPrecisionRespectedForSetValue() throws Exception {
|
||||
Calendar cal = Calendar.getInstance();
|
||||
cal.setTime(myDateInstantParser.parse("2012-01-02 22:31:02.333"));
|
||||
cal.setTimeZone(TimeZone.getTimeZone("EST"));
|
||||
|
||||
Date time = cal.getTime();
|
||||
|
||||
DateType date = new DateType();
|
||||
date.setValue(time);
|
||||
assertEquals("2012-01-02", date.getValueAsString());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testMinutePrecisionEncode() throws Exception {
|
||||
Calendar cal = Calendar.getInstance();
|
||||
cal.setTimeZone(TimeZone.getTimeZone("Europe/Berlin"));
|
||||
cal.set(1990, Calendar.JANUARY, 3, 3, 22, 11);
|
||||
|
||||
DateTimeType date = new DateTimeType();
|
||||
date.setValue(cal.getTime(), TemporalPrecisionEnum.MINUTE);
|
||||
date.setTimeZone(TimeZone.getTimeZone("EST"));
|
||||
assertEquals("1990-01-02T21:22-05:00", date.getValueAsString());
|
||||
|
||||
date.setTimeZoneZulu(true);
|
||||
assertEquals("1990-01-03T02:22Z", date.getValueAsString());
|
||||
}
|
||||
|
||||
/**
|
||||
* See HAPI #101 - https://github.com/jamesagnew/hapi-fhir/issues/101
|
||||
*/
|
||||
@Test
|
||||
public void testPrecisionRespectedForSetValueWithPrecision() throws Exception {
|
||||
Calendar cal = Calendar.getInstance();
|
||||
cal.setTime(myDateInstantParser.parse("2012-01-02 22:31:02.333"));
|
||||
cal.setTimeZone(TimeZone.getTimeZone("EST"));
|
||||
|
||||
Date time = cal.getTime();
|
||||
|
||||
DateType date = new DateType();
|
||||
date.setValue(time, TemporalPrecisionEnum.DAY);
|
||||
assertEquals("2012-01-02", date.getValueAsString());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testToHumanDisplay() {
|
||||
DateTimeType dt = new DateTimeType("2012-01-05T12:00:00-08:00");
|
||||
String human = dt.toHumanDisplay();
|
||||
ourLog.info(human);
|
||||
assertThat(human, containsString("2012"));
|
||||
assertThat(human, containsString("12"));
|
||||
}
|
||||
|
||||
public static void afterClass() {
|
||||
Locale.setDefault(ourDefaultLocale);
|
||||
}
|
||||
|
||||
@BeforeClass
|
||||
public static void beforeClass() {
|
||||
/*
|
||||
* We cache the default locale, but temporarily set it to a random value during this test. This helps ensure
|
||||
* that there are no language specific dependencies in the test.
|
||||
*/
|
||||
ourDefaultLocale = Locale.getDefault();
|
||||
|
||||
Locale[] available = { Locale.CANADA, Locale.GERMANY, Locale.TAIWAN };
|
||||
Locale newLocale = available[(int) (Math.random() * available.length)];
|
||||
Locale.setDefault(newLocale);
|
||||
|
||||
ourLog.info("Tests are running in locale: " + newLocale.getDisplayName());
|
||||
}
|
||||
|
||||
}
|
|
@ -93,7 +93,7 @@ public class ETagServerHl7OrgTest {
|
|||
|
||||
Header cl = status.getFirstHeader(Constants.HEADER_LAST_MODIFIED_LOWERCASE);
|
||||
assertNotNull(cl);
|
||||
assertEquals("Sun, 25 Nov 2012 02:34:47 GMT", cl.getValue());
|
||||
assertEquals("Sun, 25 Nov 2012 02:34:45 GMT", cl.getValue());
|
||||
}
|
||||
|
||||
@Before
|
||||
|
|
|
@ -240,6 +240,10 @@
|
|||
<action type="fix">
|
||||
Web Testing UI was not able to correctly post an STU3 transaction
|
||||
</action>
|
||||
<action type="fix">
|
||||
DateTime parser incorrectly parsed times where more than 3 digits of
|
||||
precision were provided on the seconds after the decimal point
|
||||
</action>
|
||||
</release>
|
||||
<release version="1.5" date="2016-04-20">
|
||||
<action type="fix" issue="339">
|
||||
|
|
Loading…
Reference in New Issue