Fix #101 - Calling BaseDateTimeDt#setValue(Date, TemporalPrecisionEnum) did not always actually respect the given precision when the value was encoded. Thanks to jacksonjesse for reporting!

This commit is contained in:
James Agnew 2015-02-09 14:50:13 -05:00
parent 4b8092b12e
commit c8bd93ba92
4 changed files with 98 additions and 13 deletions

View File

@ -20,11 +20,14 @@ package ca.uhn.fhir.model.primitive;
* #L%
*/
import static ca.uhn.fhir.model.api.TemporalPrecisionEnum.*;
import static ca.uhn.fhir.model.api.TemporalPrecisionEnum.DAY;
import static ca.uhn.fhir.model.api.TemporalPrecisionEnum.MILLI;
import static ca.uhn.fhir.model.api.TemporalPrecisionEnum.MONTH;
import static ca.uhn.fhir.model.api.TemporalPrecisionEnum.SECOND;
import static ca.uhn.fhir.model.api.TemporalPrecisionEnum.YEAR;
import java.text.ParseException;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Collections;
import java.util.Date;
import java.util.GregorianCalendar;
@ -330,13 +333,7 @@ public abstract class BaseDateTimeDt extends BasePrimitive<Date> {
}
/**
* Sets the precision for this datatype using field values from {@link Calendar}. Valid values are:
* <ul>
* <li>{@link Calendar#SECOND}
* <li>{@link Calendar#DAY_OF_MONTH}
* <li>{@link Calendar#MONTH}
* <li>{@link Calendar#YEAR}
* </ul>
* Sets the precision for this datatype
*
* @throws DataFormatException
*/
@ -372,15 +369,23 @@ public abstract class BaseDateTimeDt extends BasePrimitive<Date> {
updateStringValue();
}
/**
* 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
public BaseDateTimeDt setValue(Date theValue) {
clearTimeZone();
super.setValue(theValue);
setValue(theValue, getDefaultPrecisionForDatatype());
return this;
}
/**
* Sets the value of this date/time using the specified level of precision
* 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
* The date value
@ -390,8 +395,8 @@ public abstract class BaseDateTimeDt extends BasePrimitive<Date> {
*/
public void setValue(Date theValue, TemporalPrecisionEnum thePrecision) throws DataFormatException {
clearTimeZone();
super.setValue(theValue);
myPrecision = thePrecision;
super.setValue(theValue);
}
@Override

View File

@ -3,6 +3,7 @@ package ca.uhn.fhir.model.primitive;
import static org.hamcrest.Matchers.*;
import static org.junit.Assert.*;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
@ -17,6 +18,7 @@ import org.junit.Test;
import ca.uhn.fhir.context.FhirContext;
import ca.uhn.fhir.model.api.TemporalPrecisionEnum;
import ca.uhn.fhir.model.dstu.resource.Condition;
import ca.uhn.fhir.model.dstu.resource.Patient;
import ca.uhn.fhir.parser.DataFormatException;
import ca.uhn.fhir.validation.ValidationResult;
@ -33,6 +35,22 @@ public class BaseDateTimeDtTest {
myDateInstantZoneParser = FastDateFormat.getInstance("yyyy-MM-dd HH:mm:ss.SSSZ", TimeZone.getTimeZone("GMT-02:00"));
}
/**
* See #101
*/
@Test
public void testPrecision() throws Exception {
Calendar cal = Calendar.getInstance();
cal.setTime(myDateInstantParser.parse("2012-01-02 22:31:02.333"));
cal.setTimeZone(TimeZone.getTimeZone("EST"));
Patient patient = new Patient();
patient.setBirthDate(cal.getTime(), TemporalPrecisionEnum.DAY);
String out = ourCtx.newXmlParser().encodeResourceToString(patient);
assertThat(out, containsString("<birthDate value=\"2012-01-02\"/>"));
}
@Test
public void setTimezoneToZulu() {
DateTimeDt dt = new DateTimeDt(new Date(816411488000L));

View File

@ -0,0 +1,57 @@
package ca.uhn.fhir.model.primitive;
import static org.junit.Assert.assertEquals;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.TimeZone;
import org.junit.Before;
import org.junit.Test;
import ca.uhn.fhir.model.api.TemporalPrecisionEnum;
public class BaseDateTimeDtTest {
private SimpleDateFormat myDateInstantParser;
@Before
public void before() {
myDateInstantParser = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS");
}
/**
* 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();
DateDt date = new DateDt();
date.setValue(time, TemporalPrecisionEnum.DAY);
assertEquals("2012-01-02", date.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();
DateDt date = new DateDt();
date.setValue(time);
assertEquals("2012-01-02", date.getValueAsString());
}
}

View File

@ -101,6 +101,11 @@
if StAX API was configured to use a different provider. Thanks to
James Butler for reporting and figuring out where the issue was!
</action>
<action type="fix" issue="101">
Calling BaseDateTimeDt#setValue(Date, TemporalPrecisionEnum) did not always actually respect
the given precision when the value was encoded. Thanks to jacksonjesse for
reporting!
</action>
<action type="fix" issue="103">
Encoders (both XML and JSON) will no longer encode contained resources if they are
not referenced anywhere in the resource via a local reference. This is just a convenience