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 028package ca.uhn.hl7v2.model.primitive; 029import java.util.Calendar; 030import java.util.Date; 031import java.util.GregorianCalendar; 032import java.io.Serializable; 033 034import ca.uhn.hl7v2.model.DataTypeException; 035import 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") 055public 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 theDate The date 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