DateTime parser incorrectly parsed times where more than 3 digits of

precision were provided on the seconds
after the decimal point
This commit is contained in:
James Agnew 2016-05-25 19:20:51 -04:00
parent 9a4612105c
commit a5debc07a3
7 changed files with 471 additions and 46 deletions

View File

@ -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.
*/

View File

@ -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 {

View File

@ -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
*/

View File

@ -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) {

View File

@ -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

View File

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

View File

@ -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">