001 /**
002 * The contents of this file are subject to the Mozilla Public License Version 1.1
003 * (the "License"); you may not use this file except in compliance with the License.
004 * You may obtain a copy of the License at http://www.mozilla.org/MPL/
005 * Software distributed under the License is distributed on an "AS IS" basis,
006 * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License for the
007 * specific language governing rights and limitations under the License.
008 *
009 * The Original Code is "CommonDT.java". Description:
010 * "Note: The class description below has been excerpted from the Hl7 2.4 documentation"
011 *
012 * The Initial Developer of the Original Code is University Health Network. Copyright (C)
013 * 2001. All Rights Reserved.
014 *
015 * Contributor(s): ______________________________________.
016 *
017 * Alternatively, the contents of this file may be used under the terms of the
018 * GNU General Public License (the �GPL�), in which case the provisions of the GPL are
019 * applicable instead of those above. If you wish to allow use of your version of this
020 * file only under the terms of the GPL and not to allow others to use your version
021 * of this file under the MPL, indicate your decision by deleting the provisions above
022 * and replace them with the notice and other provisions required by the GPL License.
023 * If you do not delete the provisions above, a recipient may use your version of
024 * this file under either the MPL or the GPL.
025 *
026 */
027
028 package ca.uhn.hl7v2.model.primitive;
029 import java.util.Calendar;
030 import java.util.Date;
031 import java.util.GregorianCalendar;
032 import java.io.Serializable;
033
034 import ca.uhn.hl7v2.model.DataTypeException;
035 import ca.uhn.hl7v2.model.DataTypeUtil;
036
037 /**
038 * This class contains functionality used by the DT class
039 * in the version 2.3.0, 2.3.1, and 2.4 packages
040 *
041 * Note: The class description below has been excerpted from the Hl7 2.4 documentation. Sectional
042 * references made below also refer to the same documentation.
043 *
044 * Format: YYYY[MM[DD]]
045 * In prior versions of HL7, this data type was always specified to be in the format YYYYMMDD. In the current and future
046 * versions, the precision of a date may be expressed by limiting the number of digits used with the format specification
047 * YYYY[MM[DD]]. Thus, YYYY is used to specify a precision of "year," YYYYMM specifies a precision of "month,"
048 * and YYYYMMDD specifies a precision of "day."
049 * By site-specific agreement, YYYYMMDD may be used where backward compatibility must be maintained.
050 * Examples: |19880704| |199503|
051 * @author Neal Acharya
052 */
053
054 @SuppressWarnings("serial")
055 public class CommonDT implements Serializable {
056
057 private String value;
058 private int year;
059 private int month;
060 private int day;
061
062 /**
063 * Constructs a DT datatype with fields initialzed to zero and value initialized
064 * to null.
065 */
066 public CommonDT() {
067 //initialize all DT fields
068 value = null;
069 year = 0;
070 month = 0;
071 day = 0;
072 } //end constructor
073
074 /**
075 * Constructs a DT object with the given value.
076 * The stored value will be in the following
077 * format YYYY[MM[DD]].
078 */
079 public CommonDT(String val) throws DataTypeException {
080 this.setValue(val);
081 } //end constructor
082
083 /**
084 * Convenience setter which sets the value using a {@link Calendar} object. Passing in <code>null</code> clears any existing value.
085 *
086 * Note: Sets fields using maximum possible precision
087 *
088 * @param theCalendar The calendar object from which to retrieve values
089 * @since 1.1
090 */
091 public void setValue(Calendar theCalendar) throws DataTypeException {
092 if (theCalendar == null) {
093 setValue((String)null);
094 return;
095 }
096
097 int yr = theCalendar.get(Calendar.YEAR);
098 int mnth = theCalendar.get(Calendar.MONTH) + 1;
099 int dy = theCalendar.get(Calendar.DATE);
100 setYearMonthDayPrecision(yr, mnth, dy);
101 }
102
103 /**
104 * Convenience setter which sets the value using a {@link Date} object. Passing in <code>null</code> clears any existing value.
105 *
106 * Note: Sets fields using maximum possible precision
107 *
108 * @param theCalendar The calendar object from which to retrieve values
109 * @since 1.1
110 */
111 public void setValue(Date theDate) throws DataTypeException {
112 if (theDate == null) {
113 setValue((String)null);
114 return;
115 }
116
117 Calendar calendar = Calendar.getInstance();
118 calendar.setTime(theDate);
119 setValue(calendar);
120 }
121
122
123 /**
124 * Return the value as a calendar object
125 * @since 1.1
126 */
127 public Calendar getValueAsCalendar() {
128 Calendar retVal = Calendar.getInstance();
129 retVal.set(Calendar.DATE, getDay());
130 retVal.set(Calendar.MONTH, getMonth() - 1);
131 retVal.set(Calendar.YEAR, getYear());
132
133 // Truncate
134 retVal.set(Calendar.HOUR_OF_DAY, 0);
135 retVal.set(Calendar.MINUTE, 0);
136 retVal.set(Calendar.SECOND, 0);
137 retVal.set(Calendar.MILLISECOND, 0);
138
139 return retVal;
140 }
141
142
143 /**
144 * Return the value as a date object
145 * @since 1.1
146 */
147 public Date getValueAsDate() {
148 return getValueAsCalendar().getTime();
149 }
150
151
152 /**
153 * This method takes in a string HL7 date value and performs validations
154 * then sets the value field. The stored value will be in the following
155 * format YYYY[MM[DD]]. Passing in <code>null</code> clears any existing value.
156 *
157 */
158 public void setValue(String val) throws DataTypeException {
159
160 if (val != null && !val.equals("") && !val.equals("\"\"")){
161 try {
162 GregorianCalendar cal = new GregorianCalendar();
163 cal.clear();
164 cal.setLenient(false);
165
166 //check the length, must be either four, six, or eight digits
167 if ((val.length() != 4) && (val.length() != 6) && (val.length() != 8)) {
168 String msg =
169 "The length of the DT datatype value does not conform to an allowable"
170 + " format. Format should conform to YYYY[MM[DD]]";
171 DataTypeException e = new DataTypeException(msg);
172 throw e;
173 }
174
175 if (val.length() >= 4) {
176 //extract the year from the input value
177 int yrInt = Integer.parseInt(val.substring(0, 4));
178 //check to see if the year is valid by creating a Gregorian calendar object with
179 //this value. If an error occurs then processing will stop in this try block
180 cal.set(yrInt, 0, 1);
181 cal.getTime(); //for error detection
182 year = yrInt;
183 }
184
185 if (val.length() >= 6) {
186 //extract the month from the input value
187 int mnthInt = Integer.parseInt(val.substring(4, 6));
188 //check to see if the month is valid by creating a Gregorian calendar object with
189 //this value. If an error occurs then processing will stop in this try block
190 cal.set(year, mnthInt - 1, 1);
191 cal.getTime(); //for error detection
192 month = mnthInt;
193
194 }
195
196 if (val.length() == 8) {
197 //extract the day from the input value
198 int dayInt = Integer.parseInt(val.substring(6, 8));
199 //check to see if the day is valid by creating a Gregorian calendar object with
200 //the year/month/day combination. If an error occurs then processing will stop
201 // in this try block
202 cal.set(year, month - 1, dayInt);
203 cal.getTime(); //for error detection
204 day = dayInt;
205 }
206 //validations are complete now store the input value into the private value field
207 value = val;
208 } //end try
209
210 catch (DataTypeException e) {
211 throw e;
212 } //end catch
213
214 catch (Exception e) {
215 throw new DataTypeException( e );
216 } //end catch
217 } //end if
218 else {
219 //set the private value field to null or empty space.
220 value = val;
221 } //end else
222
223 } //end method
224
225 /**
226 * This method takes in an integer value for the year and performs validations,
227 * it then sets the value field formatted as an HL7 date.
228 * value with year precision (YYYY)
229 */
230 public void setYearPrecision(int yr) throws DataTypeException {
231 try {
232 GregorianCalendar cal = new GregorianCalendar();
233 cal.clear();
234 cal.setLenient(false);
235
236 //ensure that the year field is four digits long
237 if (Integer.toString(yr).length() != 4) {
238 String msg = "The input year value must be four digits long";
239 DataTypeException e = new DataTypeException(msg);
240 throw e;
241 }
242 //check is input year is valid
243 //GregorianCalendar cal = new GregorianCalendar(yr,0,1);
244 cal.set(yr, 0, 1);
245 cal.getTime(); //for error detection
246 year = yr;
247 month = 0;
248 day = 0;
249 value = Integer.toString(yr);
250 } //end try
251
252 catch (DataTypeException e) {
253 throw e;
254 } //end catch
255
256 catch (Exception e) {
257 throw new DataTypeException( e );
258 } //end catch
259
260 } //end method
261
262 /**
263 * This method takes in integer values for the year and month and performs validations,
264 * it then sets the value field formatted as an HL7 date
265 * value with year&month precision (YYYYMM).
266 * Note: The first month = 1 = January.
267 */
268 public void setYearMonthPrecision(int yr, int mnth) throws DataTypeException {
269 try {
270 GregorianCalendar cal = new GregorianCalendar();
271 cal.clear();
272 cal.setLenient(false);
273 //ensure that the year field is four digits long
274 if (Integer.toString(yr).length() != 4) {
275 String msg = "The input year value must be four digits long";
276 DataTypeException e = new DataTypeException(msg);
277 throw e;
278 }
279 //validate the input month
280 //GregorianCalendar cal = new GregorianCalendar(yr,(mnth-1),1);
281 cal.set(yr, (mnth - 1), 1);
282 cal.getTime(); //for error detection
283 year = yr;
284 month = mnth;
285 day = 0;
286 value = Integer.toString(yr) + DataTypeUtil.preAppendZeroes(mnth, 2);
287 }
288
289 catch (DataTypeException e) {
290 throw e;
291 } //end catch
292
293 catch (Exception e) {
294 throw new DataTypeException( e );
295 } //end catch
296 } //end method
297
298 /**
299 * This method takes in integer values for the year and month and day
300 * and performs validations, it then sets the value in the object
301 * formatted as an HL7 date value with year&month&day precision (YYYYMMDD).
302 */
303 public void setYearMonthDayPrecision(int yr, int mnth, int dy) throws DataTypeException {
304 try {
305 GregorianCalendar cal = new GregorianCalendar();
306 cal.clear();
307 cal.setLenient(false);
308
309 //ensure that the year field is four digits long
310 if (Integer.toString(yr).length() != 4) {
311 String msg = "The input year value must be four digits long";
312 DataTypeException e = new DataTypeException(msg);
313 throw e;
314 }
315 //validate the input month/day combination
316 cal.set(yr, (mnth - 1), dy);
317 cal.getTime(); //for error detection
318 year = yr;
319 month = mnth;
320 day = dy;
321 value = Integer.toString(yr) + DataTypeUtil.preAppendZeroes(mnth, 2) + DataTypeUtil.preAppendZeroes(dy, 2);
322 }
323
324 catch (DataTypeException e) {
325 throw e;
326 } //end catch
327
328 catch (Exception e) {
329 throw new DataTypeException( e );
330 } //end catch
331
332 } //end method
333
334 /**
335 * Returns the HL7 DT string value.
336 */
337 public String getValue() {
338 return value;
339 } //end method
340
341 /**
342 * Returns the year as an integer.
343 */
344 public int getYear() {
345 return year;
346 } //end method
347
348 /**
349 * Returns the month as an integer.
350 */
351 public int getMonth() {
352 return month;
353 } //end method
354
355 /**
356 * Returns the day as an integer.
357 */
358 public int getDay() {
359 return day;
360 } //end method
361
362
363 /**
364 * Returns a string value representing the input Gregorian Calendar object in
365 * an Hl7 Date Format.
366 */
367 public static String toHl7DTFormat(GregorianCalendar cal) throws DataTypeException {
368 String val = "";
369 try {
370 //set the input cal object so that it can report errors
371 //on it's value
372 cal.setLenient(false);
373 int calYear = cal.get(GregorianCalendar.YEAR);
374 int calMonth = cal.get(GregorianCalendar.MONTH) + 1;
375 int calDay = cal.get(GregorianCalendar.DAY_OF_MONTH);
376 CommonDT dt = new CommonDT();
377 dt.setYearMonthDayPrecision(calYear, calMonth, calDay);
378 val = dt.getValue();
379 } //end try
380
381 catch (DataTypeException e) {
382 throw e;
383 } //end catch
384
385 catch (Exception e) {
386 throw new DataTypeException( e );
387 } //end catch
388 return val;
389 } //end method
390
391 } //end class