Port in changes from RI
This commit is contained in:
parent
826c91087b
commit
88117f8d6e
|
@ -16,13 +16,13 @@ import ca.uhn.fhir.parser.DataFormatException;
|
|||
|
||||
public abstract class BaseDateTimeType extends PrimitiveType<Date> {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
static final long NANOS_PER_MILLIS = 1000000L;
|
||||
static final long NANOS_PER_SECOND = 1000000000L;
|
||||
|
||||
static final long NANOS_PER_SECOND = 1000000000L;
|
||||
private static final FastDateFormat ourHumanDateFormat = FastDateFormat.getDateInstance(FastDateFormat.MEDIUM);
|
||||
|
||||
private static final FastDateFormat ourHumanDateTimeFormat = FastDateFormat.getDateTimeInstance(FastDateFormat.MEDIUM, FastDateFormat.MEDIUM);
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
private String myFractionalSeconds;
|
||||
private TemporalPrecisionEnum myPrecision = null;
|
||||
|
@ -39,13 +39,13 @@ public abstract class BaseDateTimeType extends PrimitiveType<Date> {
|
|||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @throws DataFormatException
|
||||
* @throws IllegalArgumentException
|
||||
* If the specified precision is not allowed for this type
|
||||
*/
|
||||
public BaseDateTimeType(Date theDate, TemporalPrecisionEnum thePrecision) {
|
||||
setValue(theDate, thePrecision);
|
||||
if (isPrecisionAllowed(thePrecision) == false) {
|
||||
throw new DataFormatException("Invalid date/time string (datatype " + getClass().getSimpleName() + " does not support " + thePrecision + " precision): " + theDate);
|
||||
throw new IllegalArgumentException("Invalid date/time string (datatype " + getClass().getSimpleName() + " does not support " + thePrecision + " precision): " + theDate);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -60,16 +60,76 @@ public abstract class BaseDateTimeType extends PrimitiveType<Date> {
|
|||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @throws DataFormatException
|
||||
* @throws IllegalArgumentException
|
||||
* If the specified precision is not allowed for this type
|
||||
*/
|
||||
public BaseDateTimeType(String theString) {
|
||||
setValueAsString(theString);
|
||||
if (isPrecisionAllowed(getPrecision()) == false) {
|
||||
throw new DataFormatException("Invalid date/time string (datatype " + getClass().getSimpleName() + " does not support " + getPrecision() + " precision): " + theString);
|
||||
throw new IllegalArgumentException("Invalid date/time string (datatype " + getClass().getSimpleName() + " does not support " + getPrecision() + " precision): " + theString);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds the given amount to the field specified by theField
|
||||
*
|
||||
* @param theField
|
||||
* The field, uses constants from {@link Calendar} such as {@link Calendar#YEAR}
|
||||
* @param theValue
|
||||
* The number to add (or subtract for a negative number)
|
||||
*/
|
||||
public void add(int theField, int theValue) {
|
||||
switch (theField) {
|
||||
case Calendar.YEAR:
|
||||
setValue(DateUtils.addYears(getValue(), theValue), getPrecision());
|
||||
break;
|
||||
case Calendar.MONTH:
|
||||
setValue(DateUtils.addMonths(getValue(), theValue), getPrecision());
|
||||
break;
|
||||
case Calendar.DATE:
|
||||
setValue(DateUtils.addDays(getValue(), theValue), getPrecision());
|
||||
break;
|
||||
case Calendar.HOUR:
|
||||
setValue(DateUtils.addHours(getValue(), theValue), getPrecision());
|
||||
break;
|
||||
case Calendar.MINUTE:
|
||||
setValue(DateUtils.addMinutes(getValue(), theValue), getPrecision());
|
||||
break;
|
||||
case Calendar.SECOND:
|
||||
setValue(DateUtils.addSeconds(getValue(), theValue), getPrecision());
|
||||
break;
|
||||
case Calendar.MILLISECOND:
|
||||
setValue(DateUtils.addMilliseconds(getValue(), theValue), getPrecision());
|
||||
break;
|
||||
default:
|
||||
throw new DataFormatException("Unknown field constant: " + theField);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns <code>true</code> if the given object represents a date/time before <code>this</code> object
|
||||
*
|
||||
* @throws NullPointerException
|
||||
* If <code>this.getValue()</code> or <code>theDateTimeType.getValue()</code>
|
||||
* return <code>null</code>
|
||||
*/
|
||||
public boolean after(DateTimeType theDateTimeType) {
|
||||
validateBeforeOrAfter(theDateTimeType);
|
||||
return getValue().after(theDateTimeType.getValue());
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns <code>true</code> if the given object represents a date/time before <code>this</code> object
|
||||
*
|
||||
* @throws NullPointerException
|
||||
* If <code>this.getValue()</code> or <code>theDateTimeType.getValue()</code>
|
||||
* return <code>null</code>
|
||||
*/
|
||||
public boolean before(DateTimeType theDateTimeType) {
|
||||
validateBeforeOrAfter(theDateTimeType);
|
||||
return getValue().before(theDateTimeType.getValue());
|
||||
}
|
||||
|
||||
private void clearTimeZone() {
|
||||
myTimeZone = null;
|
||||
myTimeZoneZulu = false;
|
||||
|
@ -140,11 +200,74 @@ public abstract class BaseDateTimeType extends PrimitiveType<Date> {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the month with 1-index, e.g. 1=the first day of the month
|
||||
*/
|
||||
public Integer getDay() {
|
||||
return getFieldValue(Calendar.DAY_OF_MONTH);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the default precision for the given datatype
|
||||
*/
|
||||
protected abstract TemporalPrecisionEnum getDefaultPrecisionForDatatype();
|
||||
|
||||
private Integer getFieldValue(int theField) {
|
||||
if (getValue() == null) {
|
||||
return null;
|
||||
}
|
||||
Calendar cal = getValueAsCalendar();
|
||||
return cal.get(theField);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the hour of the day in a 24h clock, e.g. 13=1pm
|
||||
*/
|
||||
public Integer getHour() {
|
||||
return getFieldValue(Calendar.HOUR_OF_DAY);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the milliseconds within the current second.
|
||||
* <p>
|
||||
* Note that this method returns the
|
||||
* same value as {@link #getNanos()} but with less precision.
|
||||
* </p>
|
||||
*/
|
||||
public Integer getMillis() {
|
||||
return getFieldValue(Calendar.MILLISECOND);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the minute of the hour in the range 0-59
|
||||
*/
|
||||
public Integer getMinute() {
|
||||
return getFieldValue(Calendar.MINUTE);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the month with 0-index, e.g. 0=January
|
||||
*/
|
||||
public Integer getMonth() {
|
||||
return getFieldValue(Calendar.MONTH);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the nanoseconds within the current second
|
||||
* <p>
|
||||
* Note that this method returns the
|
||||
* same value as {@link #getMillis()} but with more precision.
|
||||
* </p>
|
||||
*/
|
||||
public Long getNanos() {
|
||||
if (isBlank(myFractionalSeconds)) {
|
||||
return null;
|
||||
}
|
||||
String retVal = StringUtils.rightPad(myFractionalSeconds, 9, '0');
|
||||
retVal = retVal.substring(0, 9);
|
||||
return Long.parseLong(retVal);
|
||||
}
|
||||
|
||||
private int getOffsetIndex(String theValueString) {
|
||||
int plusIndex = theValueString.indexOf('+', 16);
|
||||
int minusIndex = theValueString.indexOf('-', 16);
|
||||
|
@ -171,6 +294,13 @@ public abstract class BaseDateTimeType extends PrimitiveType<Date> {
|
|||
return myPrecision;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the second of the minute in the range 0-59
|
||||
*/
|
||||
public Integer getSecond() {
|
||||
return getFieldValue(Calendar.SECOND);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the TimeZone associated with this dateTime's value. May return <code>null</code> if no timezone was
|
||||
* supplied.
|
||||
|
@ -199,6 +329,13 @@ public abstract class BaseDateTimeType extends PrimitiveType<Date> {
|
|||
return cal;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the year, e.g. 2015
|
||||
*/
|
||||
public Integer getYear() {
|
||||
return getFieldValue(Calendar.YEAR);
|
||||
}
|
||||
|
||||
/**
|
||||
* To be implemented by subclasses to indicate whether the given precision is allowed by this type
|
||||
*/
|
||||
|
@ -272,7 +409,7 @@ public abstract class BaseDateTimeType extends PrimitiveType<Date> {
|
|||
int offsetIdx = getOffsetIndex(value);
|
||||
String time;
|
||||
if (offsetIdx == -1) {
|
||||
//throwBadDateFormat(theValue);
|
||||
// throwBadDateFormat(theValue);
|
||||
// No offset - should this be an error?
|
||||
time = value.substring(11);
|
||||
} else {
|
||||
|
@ -354,6 +491,92 @@ public abstract class BaseDateTimeType extends PrimitiveType<Date> {
|
|||
return retVal;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the month with 1-index, e.g. 1=the first day of the month
|
||||
*/
|
||||
public BaseDateTimeType setDay(int theDay) {
|
||||
setFieldValue(Calendar.DAY_OF_MONTH, theDay, null, 0, 31);
|
||||
return this;
|
||||
}
|
||||
|
||||
private void setFieldValue(int theField, int theValue, String theFractionalSeconds, int theMinimum, int theMaximum) {
|
||||
validateValueInRange(theValue, theMinimum, theMaximum);
|
||||
Calendar cal;
|
||||
if (getValue() == null) {
|
||||
cal = new GregorianCalendar(0, 0, 0);
|
||||
} else {
|
||||
cal = getValueAsCalendar();
|
||||
}
|
||||
if (theField != -1) {
|
||||
cal.set(theField, theValue);
|
||||
}
|
||||
if (theFractionalSeconds != null) {
|
||||
myFractionalSeconds = theFractionalSeconds;
|
||||
} else if (theField == Calendar.MILLISECOND) {
|
||||
myFractionalSeconds = StringUtils.leftPad(Integer.toString(theValue), 3, '0');
|
||||
}
|
||||
super.setValue(cal.getTime());
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the hour of the day in a 24h clock, e.g. 13=1pm
|
||||
*/
|
||||
public BaseDateTimeType setHour(int theHour) {
|
||||
setFieldValue(Calendar.HOUR_OF_DAY, theHour, null, 0, 23);
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the milliseconds within the current second.
|
||||
* <p>
|
||||
* Note that this method sets the
|
||||
* same value as {@link #setNanos(long)} but with less precision.
|
||||
* </p>
|
||||
*/
|
||||
public BaseDateTimeType setMillis(int theMillis) {
|
||||
setFieldValue(Calendar.MILLISECOND, theMillis, null, 0, 999);
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the minute of the hour in the range 0-59
|
||||
*/
|
||||
public BaseDateTimeType setMinute(int theMinute) {
|
||||
setFieldValue(Calendar.MINUTE, theMinute, null, 0, 59);
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the month with 0-index, e.g. 0=January
|
||||
*/
|
||||
public BaseDateTimeType setMonth(int theMonth) {
|
||||
setFieldValue(Calendar.MONTH, theMonth, null, 0, 11);
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the nanoseconds within the current second
|
||||
* <p>
|
||||
* Note that this method sets the
|
||||
* same value as {@link #setMillis(int)} but with more precision.
|
||||
* </p>
|
||||
*/
|
||||
public BaseDateTimeType setNanos(long theNanos) {
|
||||
validateValueInRange(theNanos, 0, NANOS_PER_SECOND - 1);
|
||||
String fractionalSeconds = StringUtils.leftPad(Long.toString(theNanos), 9, '0');
|
||||
|
||||
// Strip trailing 0s
|
||||
for (int i = fractionalSeconds.length(); i > 0; i--) {
|
||||
if (fractionalSeconds.charAt(i - 1) != '0') {
|
||||
fractionalSeconds = fractionalSeconds.substring(0, i);
|
||||
break;
|
||||
}
|
||||
}
|
||||
int millis = (int) (theNanos / NANOS_PER_MILLIS);
|
||||
setFieldValue(Calendar.MILLISECOND, millis, fractionalSeconds, 0, 999);
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the precision for this datatype
|
||||
*
|
||||
|
@ -367,6 +590,14 @@ public abstract class BaseDateTimeType extends PrimitiveType<Date> {
|
|||
updateStringValue();
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the second of the minute in the range 0-59
|
||||
*/
|
||||
public BaseDateTimeType setSecond(int theSecond) {
|
||||
setFieldValue(Calendar.SECOND, theSecond, null, 0, 59);
|
||||
return this;
|
||||
}
|
||||
|
||||
private BaseDateTimeType setTimeZone(String theWholeValue, String theValue) {
|
||||
|
||||
if (isBlank(theValue)) {
|
||||
|
@ -448,6 +679,55 @@ public abstract class BaseDateTimeType extends PrimitiveType<Date> {
|
|||
super.setValueAsString(theValue);
|
||||
}
|
||||
|
||||
protected void setValueAsV3String(String theV3String) {
|
||||
if (StringUtils.isBlank(theV3String)) {
|
||||
setValue(null);
|
||||
} else {
|
||||
StringBuilder b = new StringBuilder();
|
||||
String timeZone = null;
|
||||
for (int i = 0; i < theV3String.length(); i++) {
|
||||
char nextChar = theV3String.charAt(i);
|
||||
if (nextChar == '+' || nextChar == '-' || nextChar == 'Z') {
|
||||
timeZone = (theV3String.substring(i));
|
||||
break;
|
||||
}
|
||||
|
||||
// assertEquals("2013-02-02T20:13:03-05:00", DateAndTime.parseV3("20130202201303-0500").toString());
|
||||
if (i == 4 || i == 6) {
|
||||
b.append('-');
|
||||
} else if (i == 8) {
|
||||
b.append('T');
|
||||
} else if (i == 10 || i == 12) {
|
||||
b.append(':');
|
||||
}
|
||||
|
||||
b.append(nextChar);
|
||||
}
|
||||
|
||||
if (b.length() == 16)
|
||||
b.append(":00"); // schema rule, must have seconds
|
||||
if (timeZone != null && b.length() > 10) {
|
||||
if (timeZone.length() == 5) {
|
||||
b.append(timeZone.substring(0, 3));
|
||||
b.append(':');
|
||||
b.append(timeZone.substring(3));
|
||||
} else {
|
||||
b.append(timeZone);
|
||||
}
|
||||
}
|
||||
|
||||
setValueAsString(b.toString());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the year, e.g. 2015
|
||||
*/
|
||||
public BaseDateTimeType setYear(int theYear) {
|
||||
setFieldValue(Calendar.YEAR, theYear, null, 0, 9999);
|
||||
return this;
|
||||
}
|
||||
|
||||
private void throwBadDateFormat(String theValue) {
|
||||
throw new DataFormatException("Invalid date/time format: \"" + theValue + "\"");
|
||||
}
|
||||
|
@ -456,6 +736,18 @@ public abstract class BaseDateTimeType extends PrimitiveType<Date> {
|
|||
throw new DataFormatException("Invalid date/time format: \"" + theValue + "\": " + theMesssage);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a view of this date/time as a Calendar object. Note that the returned
|
||||
* Calendar object is entirely independent from <code>this</code> object. Changes to the
|
||||
* calendar will not affect <code>this</code>.
|
||||
*/
|
||||
public Calendar toCalendar() {
|
||||
Calendar retVal = Calendar.getInstance();
|
||||
retVal.setTime(getValue());
|
||||
retVal.setTimeZone(getTimeZone());
|
||||
return retVal;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a human readable version of this date/time using the system local format.
|
||||
* <p>
|
||||
|
@ -502,6 +794,18 @@ public abstract class BaseDateTimeType extends PrimitiveType<Date> {
|
|||
}
|
||||
}
|
||||
|
||||
private void validateBeforeOrAfter(DateTimeType theDateTimeType) {
|
||||
if (getValue() == null) {
|
||||
throw new NullPointerException("This BaseDateTimeType does not contain a value (getValue() returns null)");
|
||||
}
|
||||
if (theDateTimeType == null) {
|
||||
throw new NullPointerException("theDateTimeType must not be null");
|
||||
}
|
||||
if (theDateTimeType.getValue() == null) {
|
||||
throw new NullPointerException("The given BaseDateTimeType does not contain a value (theDateTimeType.getValue() returns null)");
|
||||
}
|
||||
}
|
||||
|
||||
private void validateCharAtIndexIs(String theValue, int theIndex, char theChar) {
|
||||
if (theValue.charAt(theIndex) != theChar) {
|
||||
throwBadDateFormat(theValue, "Expected character '" + theChar + "' at index " + theIndex + " but found " + theValue.charAt(theIndex));
|
||||
|
@ -514,230 +818,10 @@ public abstract class BaseDateTimeType extends PrimitiveType<Date> {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the year, e.g. 2015
|
||||
*/
|
||||
public Integer getYear() {
|
||||
return getFieldValue(Calendar.YEAR);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the month with 0-index, e.g. 0=January
|
||||
*/
|
||||
public Integer getMonth() {
|
||||
return getFieldValue(Calendar.MONTH);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the month with 1-index, e.g. 1=the first day of the month
|
||||
*/
|
||||
public Integer getDay() {
|
||||
return getFieldValue(Calendar.DAY_OF_MONTH);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the hour of the day in a 24h clock, e.g. 13=1pm
|
||||
*/
|
||||
public Integer getHour() {
|
||||
return getFieldValue(Calendar.HOUR_OF_DAY);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the minute of the hour in the range 0-59
|
||||
*/
|
||||
public Integer getMinute() {
|
||||
return getFieldValue(Calendar.MINUTE);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the second of the minute in the range 0-59
|
||||
*/
|
||||
public Integer getSecond() {
|
||||
return getFieldValue(Calendar.SECOND);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the milliseconds within the current second.
|
||||
* <p>
|
||||
* Note that this method returns the
|
||||
* same value as {@link #getNanos()} but with less precision.
|
||||
* </p>
|
||||
*/
|
||||
public Integer getMillis() {
|
||||
return getFieldValue(Calendar.MILLISECOND);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the nanoseconds within the current second
|
||||
* <p>
|
||||
* Note that this method returns the
|
||||
* same value as {@link #getMillis()} but with more precision.
|
||||
* </p>
|
||||
*/
|
||||
public Long getNanos() {
|
||||
if (isBlank(myFractionalSeconds)) {
|
||||
return null;
|
||||
}
|
||||
String retVal = StringUtils.rightPad(myFractionalSeconds, 9, '0');
|
||||
retVal = retVal.substring(0, 9);
|
||||
return Long.parseLong(retVal);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the year, e.g. 2015
|
||||
*/
|
||||
public BaseDateTimeType setYear(int theYear) {
|
||||
setFieldValue(Calendar.YEAR, theYear, null, 0, 9999);
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the month with 0-index, e.g. 0=January
|
||||
*/
|
||||
public BaseDateTimeType setMonth(int theMonth) {
|
||||
setFieldValue(Calendar.MONTH, theMonth, null, 0, 11);
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the month with 1-index, e.g. 1=the first day of the month
|
||||
*/
|
||||
public BaseDateTimeType setDay(int theDay) {
|
||||
setFieldValue(Calendar.DAY_OF_MONTH, theDay, null, 0, 31);
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the hour of the day in a 24h clock, e.g. 13=1pm
|
||||
*/
|
||||
public BaseDateTimeType setHour(int theHour) {
|
||||
setFieldValue(Calendar.HOUR_OF_DAY, theHour, null, 0, 23);
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the minute of the hour in the range 0-59
|
||||
*/
|
||||
public BaseDateTimeType setMinute(int theMinute) {
|
||||
setFieldValue(Calendar.MINUTE, theMinute, null, 0, 59);
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the second of the minute in the range 0-59
|
||||
*/
|
||||
public BaseDateTimeType setSecond(int theSecond) {
|
||||
setFieldValue(Calendar.SECOND, theSecond, null, 0, 59);
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the milliseconds within the current second.
|
||||
* <p>
|
||||
* Note that this method sets the
|
||||
* same value as {@link #setNanos(long)} but with less precision.
|
||||
* </p>
|
||||
*/
|
||||
public BaseDateTimeType setMillis(int theMillis) {
|
||||
setFieldValue(Calendar.MILLISECOND, theMillis, null, 0, 999);
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the nanoseconds within the current second
|
||||
* <p>
|
||||
* Note that this method sets the
|
||||
* same value as {@link #setMillis(int)} but with more precision.
|
||||
* </p>
|
||||
*/
|
||||
public BaseDateTimeType setNanos(long theNanos) {
|
||||
validateValueInRange(theNanos, 0, NANOS_PER_SECOND-1);
|
||||
String fractionalSeconds = StringUtils.leftPad(Long.toString(theNanos), 9, '0');
|
||||
|
||||
// Strip trailing 0s
|
||||
for (int i = fractionalSeconds.length(); i > 0; i--) {
|
||||
if (fractionalSeconds.charAt(i-1) != '0') {
|
||||
fractionalSeconds = fractionalSeconds.substring(0, i);
|
||||
break;
|
||||
}
|
||||
}
|
||||
int millis = (int)(theNanos / NANOS_PER_MILLIS);
|
||||
setFieldValue(Calendar.MILLISECOND, millis, fractionalSeconds, 0, 999);
|
||||
return this;
|
||||
}
|
||||
|
||||
private void setFieldValue(int theField, int theValue, String theFractionalSeconds, int theMinimum, int theMaximum) {
|
||||
validateValueInRange(theValue, theMinimum, theMaximum);
|
||||
Calendar cal;
|
||||
if (getValue() == null) {
|
||||
cal = new GregorianCalendar(0, 0, 0);
|
||||
} else {
|
||||
cal = getValueAsCalendar();
|
||||
}
|
||||
if (theField != -1) {
|
||||
cal.set(theField, theValue);
|
||||
}
|
||||
if (theFractionalSeconds != null) {
|
||||
myFractionalSeconds = theFractionalSeconds;
|
||||
} else if (theField == Calendar.MILLISECOND) {
|
||||
myFractionalSeconds = StringUtils.leftPad(Integer.toString(theValue), 3, '0');
|
||||
}
|
||||
super.setValue(cal.getTime());
|
||||
}
|
||||
|
||||
private void validateValueInRange(long theValue, long theMinimum, long theMaximum) {
|
||||
if (theValue < theMinimum || theValue > theMaximum) {
|
||||
throw new IllegalArgumentException("Value " + theValue + " is not between allowable range: " + theMinimum + " - " + theMaximum);
|
||||
}
|
||||
}
|
||||
|
||||
private Integer getFieldValue(int theField) {
|
||||
if (getValue() == null) {
|
||||
return null;
|
||||
}
|
||||
Calendar cal = getValueAsCalendar();
|
||||
return cal.get(theField);
|
||||
}
|
||||
|
||||
protected void setValueAsV3String(String theV3String) {
|
||||
if (StringUtils.isBlank(theV3String)) {
|
||||
setValue(null);
|
||||
} else {
|
||||
StringBuilder b = new StringBuilder();
|
||||
String timeZone = null;
|
||||
for (int i = 0; i < theV3String.length(); i++) {
|
||||
char nextChar = theV3String.charAt(i);
|
||||
if (nextChar == '+' || nextChar == '-' || nextChar == 'Z') {
|
||||
timeZone = (theV3String.substring(i));
|
||||
break;
|
||||
}
|
||||
|
||||
// assertEquals("2013-02-02T20:13:03-05:00", DateAndTime.parseV3("20130202201303-0500").toString());
|
||||
if (i == 4 || i == 6) {
|
||||
b.append('-');
|
||||
} else if (i == 8) {
|
||||
b.append('T');
|
||||
} else if (i == 10 || i == 12) {
|
||||
b.append(':');
|
||||
}
|
||||
|
||||
b.append(nextChar);
|
||||
}
|
||||
|
||||
if (b.length() == 16)
|
||||
b.append(":00"); // schema rule, must have seconds
|
||||
if (timeZone != null && b.length() > 10) {
|
||||
if (timeZone.length() ==5) {
|
||||
b.append(timeZone.substring(0, 3));
|
||||
b.append(':');
|
||||
b.append(timeZone.substring(3));
|
||||
}else {
|
||||
b.append(timeZone);
|
||||
}
|
||||
}
|
||||
|
||||
setValueAsString(b.toString());
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -3,12 +3,7 @@ package org.hl7.fhir.dstu3.model;
|
|||
import static org.hamcrest.Matchers.containsString;
|
||||
import static org.hamcrest.Matchers.either;
|
||||
import static org.hamcrest.Matchers.endsWith;
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertNotNull;
|
||||
import static org.junit.Assert.assertNull;
|
||||
import static org.junit.Assert.assertThat;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
import static org.junit.Assert.fail;
|
||||
import static org.junit.Assert.*;
|
||||
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.time.LocalDateTime;
|
||||
|
@ -55,6 +50,65 @@ public class BaseDateTimeTypeDstu3Test {
|
|||
assertEquals("1995-11-15T04:58:08Z", dt.getValueAsString());
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void testAfter() {
|
||||
assertTrue(new DateTimeType("2011-01-01T12:12:12Z").after(new DateTimeType("2011-01-01T12:12:11Z")));
|
||||
assertFalse(new DateTimeType("2011-01-01T12:12:11Z").after(new DateTimeType("2011-01-01T12:12:12Z")));
|
||||
assertFalse(new DateTimeType("2011-01-01T12:12:12Z").after(new DateTimeType("2011-01-01T12:12:12Z")));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testBefore() {
|
||||
assertFalse(new DateTimeType("2011-01-01T12:12:12Z").before(new DateTimeType("2011-01-01T12:12:11Z")));
|
||||
assertTrue(new DateTimeType("2011-01-01T12:12:11Z").before(new DateTimeType("2011-01-01T12:12:12Z")));
|
||||
assertFalse(new DateTimeType("2011-01-01T12:12:12Z").before(new DateTimeType("2011-01-01T12:12:12Z")));
|
||||
}
|
||||
|
||||
@Test()
|
||||
public void testAfterNull() {
|
||||
try {
|
||||
assertTrue(new DateTimeType().after(new DateTimeType("2011-01-01T12:12:11Z")));
|
||||
fail();
|
||||
} catch (NullPointerException e) {
|
||||
assertEquals("This BaseDateTimeType does not contain a value (getValue() returns null)", e.getMessage());
|
||||
}
|
||||
try {
|
||||
assertTrue(new DateTimeType("2011-01-01T12:12:11Z").after(new DateTimeType()));
|
||||
fail();
|
||||
} catch (NullPointerException e) {
|
||||
assertEquals("The given BaseDateTimeType does not contain a value (theDateTimeType.getValue() returns null)", e.getMessage());
|
||||
}
|
||||
try {
|
||||
assertTrue(new DateTimeType("2011-01-01T12:12:11Z").after(null));
|
||||
fail();
|
||||
} catch (NullPointerException e) {
|
||||
assertEquals("theDateTimeType must not be null", e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
@Test()
|
||||
public void testBeforeNull1() {
|
||||
try {
|
||||
assertTrue(new DateTimeType().before(new DateTimeType("2011-01-01T12:12:11Z")));
|
||||
fail();
|
||||
} catch (NullPointerException e) {
|
||||
assertEquals("This BaseDateTimeType does not contain a value (getValue() returns null)", e.getMessage());
|
||||
}
|
||||
try {
|
||||
assertTrue(new DateTimeType("2011-01-01T12:12:11Z").before(new DateTimeType()));
|
||||
fail();
|
||||
} catch (NullPointerException e) {
|
||||
assertEquals("The given BaseDateTimeType does not contain a value (theDateTimeType.getValue() returns null)", e.getMessage());
|
||||
}
|
||||
try {
|
||||
assertTrue(new DateTimeType("2011-01-01T12:12:11Z").before(null));
|
||||
fail();
|
||||
} catch (NullPointerException e) {
|
||||
assertEquals("theDateTimeType must not be null", e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Test for #57
|
||||
*/
|
||||
|
@ -64,13 +118,13 @@ public class BaseDateTimeTypeDstu3Test {
|
|||
try {
|
||||
new DateType("2001-01-02T11:13:33");
|
||||
fail();
|
||||
} catch (DataFormatException e) {
|
||||
} catch (IllegalArgumentException e) {
|
||||
assertThat(e.getMessage(), containsString("precision"));
|
||||
}
|
||||
try {
|
||||
new InstantType("2001-01-02");
|
||||
fail();
|
||||
} catch (DataFormatException e) {
|
||||
} catch (IllegalArgumentException e) {
|
||||
assertThat(e.getMessage(), containsString("precision"));
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue