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 * 010 * 011 * The Initial Developer of the Original Code is University Health Network. Copyright (C) 012 * 2001. All Rights Reserved. 013 * 014 * Contributor(s): ______________________________________. 015 * 016 * Alternatively, the contents of this file may be used under the terms of the 017 * GNU General Public License (the "GPL"), in which case the provisions of the GPL are 018 * applicable instead of those above. If you wish to allow use of your version of this 019 * file only under the terms of the GPL and not to allow others to use your version 020 * of this file under the MPL, indicate your decision by deleting the provisions above 021 * and replace them with the notice and other provisions required by the GPL License. 022 * If you do not delete the provisions above, a recipient may use your version of 023 * this file under either the MPL or the GPL. 024 * 025 */ 026 027package ca.uhn.hl7v2.model.primitive; 028 029import ca.uhn.hl7v2.model.DataTypeException; 030import ca.uhn.hl7v2.model.DataTypeUtil; 031 032import java.io.Serializable; 033import java.util.Calendar; 034import java.util.Date; 035import java.util.GregorianCalendar; 036 037/** 038 * <p> 039 * This class contains functionality used by the TS class 040 * in the version 2.3.0, 2.3.1, and 2.4 packages 041 * </p> 042 * 043 * <p> 044 * Note: The class description below has been excerpted from the Hl7 2.4 documentation. Sectional 045 * references made below also refer to the same documentation. 046 * </p> 047 * 048 * <p> 049 * Format: YYYY[MM[DD[HHMM[SS[.S[S[S[S]]]]]]]][+/-ZZZZ]^<degree of precision> 050 * </p> 051 * 052 * <p> 053 * Contains the exact time of an event, including the date and time. The date portion of a time stamp follows the rules of a 054 * date field and the time portion follows the rules of a time field. The time zone (+/-ZZZZ) is represented as +/-HHMM 055 * offset from UTC (formerly Greenwich Mean Time (GMT)), where +0000 or -0000 both represent UTC (without offset). 056 * The specific data representations used in the HL7 encoding rules are compatible with ISO 8824-1987(E). 057 * In prior versions of HL7, an optional second component indicates the degree of precision of the time stamp (Y = year, L 058 * = month, D = day, H = hour, M = minute, S = second). This optional second component is retained only for purposes of 059 * backward compatibility. 060 * </p> 061 * 062 * <p> 063 * By site-specific agreement, YYYYMMDD[HHMM[SS[.S[S[S[S]]]]]][+/-ZZZZ]^<degree of precision> may be used 064 * where backward compatibility must be maintained. 065 * In the current and future versions of HL7, the precision is indicated by limiting the number of digits used, unless the 066 * optional second component is present. Thus, YYYY is used to specify a precision of "year," YYYYMM specifies a 067 * precision of "month," YYYYMMDD specifies a precision of "day," YYYYMMDDHH is used to specify a precision of 068 * "hour," YYYYMMDDHHMM is used to specify a precision of "minute," YYYYMMDDHHMMSS is used to specify a 069 * precision of seconds, and YYYYMMDDHHMMSS.SSSS is used to specify a precision of ten thousandths of a second. 070 * In each of these cases, the time zone is an optional component. Note that if the time zone is not included, the timezone 071 * defaults to that of the local time zone of the sender. Also note that a TS valued field with the HHMM part set to "0000" 072 * represents midnight of the night extending from the previous day to the day given by the YYYYMMDD part (see example 073 * below). Maximum length of the time stamp is 26. 074 * </p> 075 * <p> 076 * Examples: <br/> 077 * |19760704010159-0500|<br/> 078 * 1:01:59 on July 4, 1976 in the Eastern Standard Time zone (USA).<br/> 079 * |19760704010159-0400|<br/> 080 * 1:01:59 on July 4, 1976 in the Eastern Daylight Saving Time zone (USA).<br/> 081 * |198807050000|<br/> 082 * Midnight of the night extending from July 4 to July 5, 1988 in the local time zone of the sender.<br/> 083 * |19880705|<br/> 084 * Same as prior example, but precision extends only to the day. Could be used for a birthdate, if the time of birth is 085 * unknown.<br/> 086 * |19981004010159+0100|<br/> 087 * 1:01:59 on October 4, 1998 in Amsterdam, NL. (Time zone=+0100).<br/> 088 * </p> 089 * <p> 090 * The HL7 Standard strongly recommends that all systems routinely send the time zone offset but does not require it. All 091 * HL7 systems are required to accept the time zone offset, but its implementation is application specific. For many 092 * applications the time of interest is the local time of the sender. For example, an application in the Eastern Standard Time 093 * zone receiving notification of an admission that takes place at 11:00 PM in San Francisco on December 11 would prefer 094 * to treat the admission as having occurred on December 11 rather than advancing the date to December 12. 095 * </p> 096 * <p> 097 * Note: The time zone [+/-ZZZZ], when used, is restricted to legally-defined time zones and is represented in HHMM 098 * format. 099 * </p> 100 * <p> 101 * One exception to this rule would be a clinical system that processed patient data collected in a clinic and a nearby hospital 102 * that happens to be in a different time zone. Such applications may choose to convert the data to a common 103 * representation. Similar concerns apply to the transitions to and from daylight saving time. HL7 supports such requirements 104 * by requiring that the time zone information be present when the information is sent. It does not, however, specify which of 105 * the treatments discussed here will be applied by the receiving system. 106 * </p> 107 * @author Neal Acharya 108 */ 109 110@SuppressWarnings("serial") 111public class CommonTS implements Serializable { 112 113 private CommonDT dt; 114 private CommonTM tm; 115 116 /** Creates new ValidTS 117 * zero argument constructor. 118 * Creates an uninitailized TS datatype 119 */ 120 public CommonTS() { 121 } //zero arg constructor 122 123 /** 124 * Constructs a TS object with the given value. 125 * The stored value will be in the following 126 * format YYYY[MM[DD[HHMM[SS[.S[S[S[S]]]]]]]][+/-ZZZZ] 127 */ 128 public CommonTS(String val) throws DataTypeException { 129 this.setValue(val); 130 } //end constructor 131 132 /** 133 * Returns the day as an integer. 134 */ 135 public int getDay() { 136 int day = 0; 137 if (dt != null) { 138 day = dt.getDay(); 139 } //end if 140 return day; 141 } //end method 142 143 /** 144 * Returns the fractional second value as a float. 145 */ 146 public float getFractSecond() { 147 float fractionOfSec = 0; 148 if (tm != null) { 149 fractionOfSec = tm.getFractSecond(); 150 } //end if 151 return fractionOfSec; 152 } //end method 153 154 /** 155 * Returns the GMT offset value as an integer. 156 */ 157 public int getGMTOffset() { 158 int offSet = 0; 159 if (tm != null) { 160 offSet = tm.getGMTOffset(); 161 } //end if 162 return offSet; 163 } //end method 164 165 /** 166 * Returns the hour as an integer. 167 */ 168 public int getHour() { 169 int hour = 0; 170 if (tm != null) { 171 hour = tm.getHour(); 172 } //end if 173 return hour; 174 } //end method 175 176 /** 177 * Returns the minute as an integer. 178 */ 179 public int getMinute() { 180 int minute = 0; 181 if (tm != null) { 182 minute = tm.getMinute(); 183 } //end if 184 return minute; 185 } //end method 186 187 /** 188 * Returns the month as an integer. 189 */ 190 public int getMonth() { 191 int month = 0; 192 if (dt != null) { 193 month = dt.getMonth(); 194 } //end if 195 return month; 196 } //end method 197 198 /** 199 * Returns the second as an integer. 200 */ 201 public int getSecond() { 202 int seconds = 0; 203 if (tm != null) { 204 seconds = tm.getSecond(); 205 } //end if 206 return seconds; 207 } //end method 208 209 /** 210 * Returns the HL7 TS string value. 211 */ 212 public String getValue() { 213 String value = null; 214 if (dt != null) { 215 value = dt.getValue(); 216 } //end if 217 if (tm != null && value != null && !value.equals("")) { 218 if (tm.getValue() != null && !tm.getValue().equals("")) { 219 //here we know we have a delete value or separate date and the time values supplied 220 if (tm.getValue().equals("\"\"") && dt.getValue().equals("\"\"")) { 221 //set value to the delete value ("") 222 value = "\"\""; 223 } 224 else{ 225 //set value to date concatonated with time value 226 value = value + tm.getValue(); 227 } 228 } //end if 229 if (tm.getValue() == null || tm.getValue().equals("")) { 230 //here we know we both have the date and just the time offset value 231 //change the offset value from an integer to a signed string 232 int offset = tm.getGMTOffset(); 233 String offsetStr = ""; 234 if (offset != CommonTM.GMT_OFFSET_NOT_SET_VALUE) { 235 offsetStr = DataTypeUtil.preAppendZeroes(Math.abs(offset), 4); 236 if (tm.getGMTOffset() >= 0) { 237 offsetStr = "+" + offsetStr; 238 } //end if 239 else { 240 offsetStr = "-" + offsetStr; 241 } //end else 242 } 243 value = value + offsetStr; 244 } //end if 245 } //end if 246 return value; 247 } //end method 248 249 /** 250 * Return the value as a calendar object. If the value is null (e.g. no value has 251 * been set), returns null 252 * 253 * @since 1.1 254 */ 255 public Calendar getValueAsCalendar() { 256 if (getValue() == null) { 257 return null; 258 } 259 260 Calendar retVal = tm.getValueAsCalendar(); 261 262 retVal.set(Calendar.YEAR, getYear()); 263 retVal.set(Calendar.MONTH, getMonth() - 1); 264 retVal.set(Calendar.DATE, getDay()); 265 266 return retVal; 267 } 268 269 /** 270 * Return the value as a date objectIf the value is null (e.g. no value has 271 * been set), returns null 272 * 273 * @since 1.1 274 */ 275 public Date getValueAsDate() { 276 if (getValue() == null) { 277 return null; 278 } 279 280 return getValueAsCalendar().getTime(); 281 } 282 283 /** 284 * Returns the year as an integer. 285 */ 286 public int getYear() { 287 int year = 0; 288 if (dt != null) { 289 year = dt.getYear(); 290 } //end if 291 return year; 292 } //end method 293 294 295 /** 296 * This method takes in integer values for the year, month, day, hour 297 * and minute and performs validations, it then sets the value in the object 298 * formatted as an HL7 Time Stamp value with year&month&day&hour&minute precision (YYYYMMDDHHMM). 299 */ 300 public void setDateMinutePrecision(int yr, int mnth, int dy, int hr, int min) throws DataTypeException { 301 try { 302 //set the value of the date object to the input date value 303 this.setDatePrecision(yr, mnth, dy); 304 //create new time object is there isn't one 305 if (tm == null) { 306 tm = new CommonTM(); 307 } 308 //set the value of the time object to the minute precision with the input values 309 tm.setHourMinutePrecision(hr, min); 310 } //end try 311 312 catch (DataTypeException e) { 313 throw e; 314 } //end catch 315 316 catch (Exception e) { 317 throw new DataTypeException(e); 318 } //end catch 319 } //end method 320 321 322 /** 323 * This method takes in integer values for the year and month and day 324 * and performs validations, it then sets the value in the object 325 * formatted as an HL7 Time Stamp value with year&month&day precision (YYYYMMDD). 326 * 327 */ 328 public void setDatePrecision(int yr, int mnth, int dy) throws DataTypeException { 329 try { 330 //create date object if there isn't one 331 if (dt == null) { 332 dt = new CommonDT(); 333 } 334 //set the value of the date object to the input date value 335 dt.setYearMonthDayPrecision(yr, mnth, dy); 336 //clear the time value object 337 tm = null; 338 } //end try 339 340 catch (DataTypeException e) { 341 throw e; 342 } //end catch 343 344 catch (Exception e) { 345 throw new DataTypeException(e); 346 } //end catch 347 } //end method 348 349 /** 350 * This method takes in integer values for the year, month, day, hour, minute, seconds, 351 * and fractional seconds (going to the tenthousandths precision). 352 * The method performs validations and then sets the value in the object formatted as an 353 * HL7 time value with a precision that starts from the year and goes down to the tenthousandths 354 * of a second (YYYYMMDDHHMMSS.SSSS). 355 * The Gmt Offset will not be effected. 356 * Note: all of the precisions from tenths down to 357 * tenthousandths of a second are optional. If the precision goes below tenthousandths 358 * of a second then the second value will be rounded to the nearest tenthousandths of a second. 359 */ 360 public void setDateSecondPrecision(int yr, int mnth, int dy, int hr, int min, float sec) throws DataTypeException { 361 try { 362 //set the value of the date object to the input date value 363 this.setDatePrecision(yr, mnth, dy); 364 //create new time object is there isn't one 365 if (tm == null) { 366 tm = new CommonTM(); 367 } 368 //set the value of the time object to the second precision with the input values 369 tm.setHourMinSecondPrecision(hr, min, sec); 370 } //end try 371 372 catch (DataTypeException e) { 373 throw e; 374 } //end catch 375 376 catch (Exception e) { 377 throw new DataTypeException(e); 378 } //end catch 379 } //end method 380 381 /** 382 * This method takes in the four digit (signed) GMT offset and sets the offset 383 * field 384 */ 385 public void setOffset(int signedOffset) throws DataTypeException { 386 try { 387 //create new time object is there isn't one 388 if (tm == null) { 389 tm = new CommonTM(); 390 } 391 //set the offset value of the time object to the input value 392 tm.setOffset(signedOffset); 393 } 394 395 catch (DataTypeException e) { 396 throw e; 397 } //end catch 398 399 catch (Exception e) { 400 throw new DataTypeException(e); 401 } //end catch 402 } //end method 403 404 /** 405 * Convenience setter which sets the value using a {@link Calendar} object. 406 * Passing in <code>null</code> clears any existing value. 407 * 408 * Note: Sets fields using precision up to the millisecond, including timezone offset 409 * 410 * @param theCalendar The calendar object from which to retrieve values 411 * @since 1.1 412 */ 413 public void setValue(Calendar theCalendar) throws DataTypeException { 414 if (theCalendar == null) { 415 setValue((String)null); 416 return; 417 } 418 419 int yr = theCalendar.get(Calendar.YEAR); 420 int mnth = theCalendar.get(Calendar.MONTH) + 1; 421 int dy = theCalendar.get(Calendar.DATE); 422 int hr = theCalendar.get(Calendar.HOUR_OF_DAY); 423 int min = theCalendar.get(Calendar.MINUTE); 424 float sec = theCalendar.get(Calendar.SECOND) + (theCalendar.get(Calendar.MILLISECOND) / 1000.0F); 425 setDateSecondPrecision(yr, mnth, dy, hr, min, sec); 426 427 // 3410095: care for integer overflow and timezones not at the full hour, e.g. India 428 int timeZoneOffset = theCalendar.get(Calendar.ZONE_OFFSET) + theCalendar.get(Calendar.DST_OFFSET); 429 int hourOffset= timeZoneOffset / (1000 * 60 * 60); 430 int minuteOffset = (timeZoneOffset / (1000 * 60)) % 60; 431 int zoneOffset = hourOffset * 100 + minuteOffset; 432 setOffset(zoneOffset); 433 } 434 435 /** 436 * Convenience setter which sets the value using a {@link Calendar} object. Passing in <code>null</code> clears any existing value. 437 * 438 * Note: Sets fields using precision up to the millisecond, and sets the timezone offset to 439 * the current system offset 440 * 441 * @param theDate The calendar object from which to retrieve values 442 * @since 1.1 443 */ 444 public void setValue(Date theDate) throws DataTypeException { 445 if (theDate == null) { 446 setValue((String)null); 447 return; 448 } 449 450 GregorianCalendar cal = new GregorianCalendar(); 451 cal.setTime(theDate); 452 setValue(cal); 453 } 454 455 /** 456 * This method takes in a string HL7 Time Stamp value and performs validations. 457 * The stored value will be in the following 458 * format YYYY[MM[DD[HHMM[SS[.S[S[S[S]]]]]]]][+/-ZZZZ]. 459 * Note: Trailing zeros supplied in the time value (HHMM[SS[.S[S[S[S]]]]]]) 460 * and GMT offset ([+/-ZZZZ]) will be preserved. 461 * Note: If the GMT offset is not supplied then the local 462 * time zone (using standard time zone format which is not modified for daylight savings) 463 * will be stored as a default. Passing in <code>null</code> clears any existing value. 464 */ 465 public void setValue(String val) throws DataTypeException { 466 if (val != null && !val.equals("") && !val.equals("\"\"")) { 467 try { 468 //check the length of the input value, ensure that it is no less than 469 //8 characters in length 470 if (val.length() < 4) { 471 String msg = "The length of the TS datatype value must be at least 4 characters in length."; 472 DataTypeException e = new DataTypeException(msg); 473 throw e; 474 } 475 476 //check the length of the input value, ensure that it is not greater 477 //than 24 characters in length 478 if (val.length() > 24) { 479 String msg = "The length of the TS datatype value must not be more than 24 characters in length."; 480 DataTypeException e = new DataTypeException(msg); 481 throw e; 482 } 483 484 //at this point we know that we have a value that should conform to the DT 485 //datatype and possibly a value that should conform to the TM datatype 486 String dateVal = null; 487 String timeVal = null; 488 String timeValLessOffset = null; 489 int sp = val.indexOf("+"); 490 int sm = val.indexOf("-"); 491 int indexOfSign = -1; 492 boolean offsetExists = false; 493 boolean timeValIsOffsetOnly = false; 494 if ((sp != -1) || (sm != -1)) { 495 offsetExists = true; 496 } 497 if (sp != -1) 498 indexOfSign = sp; 499 if (sm != -1) 500 indexOfSign = sm; 501 502 if (!offsetExists) { 503 if (val.length() <= 8) { 504 dateVal = val; 505 } 506 else { 507 //here we know that a time value is present 508 dateVal = val.substring(0, 8); 509 timeVal = val.substring(8); 510 timeValLessOffset = timeVal; 511 } 512 } //offset not exist 513 514 if (offsetExists) { 515 if (indexOfSign > 8) { 516 dateVal = val.substring(0, 8); 517 timeVal = val.substring(8); 518 timeValLessOffset = val.substring(8, indexOfSign); 519 } 520 else { 521 //we know that the time val is simply the offset 522 dateVal = val.substring(0, indexOfSign); 523 timeVal = val.substring(indexOfSign); 524 timeValIsOffsetOnly = true; 525 } 526 } //offset exists 527 528 //create date object 529 dt = new CommonDT(); 530 //set the value of the date object to the input date value 531 dt.setValue(dateVal); 532 //if the offset does not exist and a timevalue does not exist then 533 //we must provide a default offset = to the local time zone 534 if (timeVal == null && !offsetExists) { 535// int defaultOffset = DataTypeUtil.getLocalGMTOffset(); 536 tm = new CommonTM(); 537 //tm.setOffset(defaultOffset); 538 tm.setValue(""); 539 } //end if 540 541 //if we have a time value then make a new time object and set it to the 542 //input time value (as long as the time val has time + offset or just time only) 543 if (timeVal != null && !timeValIsOffsetOnly) { 544 // must make sure that the time component contains both hours 545 // at the very least -- must be at least 2 chars in length. 546 // Note: this changed as of v2.5, before hours AND minutes were required. 547 if (timeValLessOffset.length() < 2) { 548 String msg = 549 "The length of the time component for the TM datatype" 550 + " value does not conform to the allowable format" 551 + " YYYY[MM[DD[HH[MM[SS[.S[S[S[S]]]]]]]]][+/-ZZZZ]."; 552 DataTypeException e = new DataTypeException(msg); 553 throw e; 554 } //end if 555 tm = new CommonTM(); 556 tm.setValue(timeVal); 557 } //end if 558 559 //if we have a time value and it only has the offset then make a new 560 //time object and set the offset value to the input value 561 if (timeVal != null && timeValIsOffsetOnly) { 562 //we know that the time value is just the offset so we 563 //must check to see if it is the right length before setting the 564 //offset field in the tm object 565 if (timeVal.length() != 5) { 566 String msg = 567 "The length of the GMT offset for the TM datatype value does" 568 + " not conform to the allowable format [+/-ZZZZ]"; 569 DataTypeException e = new DataTypeException(msg); 570 throw e; 571 } //end if 572 tm = new CommonTM(); 573 //first extract the + sign from the offset value string if it exists 574 if (timeVal.indexOf("+") == 0) { 575 timeVal = timeVal.substring(1); 576 } //end if 577 int signedOffset = Integer.parseInt(timeVal); 578 tm.setOffset(signedOffset); 579 } //end if 580 } //end try 581 582 catch (DataTypeException e) { 583 throw e; 584 } //end catch 585 586 catch (Exception e) { 587 throw new DataTypeException(e); 588 } //end catch 589 } //end if 590 else { 591 //set the private value field to null or empty space. 592 if (val == null) { 593 dt = null; 594 tm = null; 595 } //end if 596 if (val != null && val.equals("")) { 597 dt = new CommonDT(); 598 dt.setValue(""); 599 tm = new CommonTM(); 600 tm.setValue(""); 601 } //end if 602 if (val != null && val.equals("\"\"")) { 603 dt = new CommonDT(); 604 dt.setValue("\"\""); 605 tm = new CommonTM(); 606 tm.setValue("\"\""); 607 } //end if 608 } //end else 609 610 } // end method 611 612 /** 613 * Convenience setter which sets the value using a {@link Calendar} object. Passing in <code>null</code> clears any existing value. 614 * 615 * Note: Sets fields using precision up to the minute 616 * 617 * @param theCalendar The calendar object from which to retrieve values 618 * @since 1.1 619 */ 620 public void setValueToMinute(Calendar theCalendar) throws DataTypeException { 621 if (theCalendar == null) { 622 setValue((String)null); 623 return; 624 } 625 626 int yr = theCalendar.get(Calendar.YEAR); 627 int mnth = theCalendar.get(Calendar.MONTH) + 1; 628 int dy = theCalendar.get(Calendar.DATE); 629 int hr = theCalendar.get(Calendar.HOUR_OF_DAY); 630 int min = theCalendar.get(Calendar.MINUTE); 631 setDateMinutePrecision(yr, mnth, dy, hr, min); 632 633 } 634 635 /** 636 * Convenience setter which sets the value using a {@link Date} object. Passing in <code>null</code> clears any existing value. 637 * 638 * Note: Sets fields using precision up to the minute 639 * 640 * @param theDate The date object from which to retrieve values 641 * @since 1.1 642 */ 643 public void setValueToMinute(Date theDate) throws DataTypeException { 644 if (theDate == null) { 645 setValue((String)null); 646 return; 647 } 648 649 Calendar calendar = Calendar.getInstance(); 650 calendar.setTime(theDate); 651 setValueToMinute(calendar); 652 } 653 654 /** 655 * Convenience setter which sets the value using a {@link Calendar} object. Passing in <code>null</code> clears any existing value. 656 * 657 * Note: Sets fields using precision up to the second 658 * 659 * @param theCalendar The calendar object from which to retrieve values 660 * @since 1.1 661 */ 662 public void setValueToSecond(Calendar theCalendar) throws DataTypeException { 663 if (theCalendar == null) { 664 setValue((String)null); 665 return; 666 } 667 668 int yr = theCalendar.get(Calendar.YEAR); 669 int mnth = theCalendar.get(Calendar.MONTH) + 1; 670 int dy = theCalendar.get(Calendar.DATE); 671 int hr = theCalendar.get(Calendar.HOUR_OF_DAY); 672 int min = theCalendar.get(Calendar.MINUTE); 673 int sec = theCalendar.get(Calendar.SECOND); 674 setDateSecondPrecision(yr, mnth, dy, hr, min, sec); 675 } 676 677 /** 678 * Convenience setter which sets the value using a {@link Date} object. Passing in <code>null</code> clears any existing value. 679 * 680 * Note: Sets fields using precision up to the second 681 * 682 * @param theDate The date object from which to retrieve values 683 * @since 1.1 684 */ 685 public void setValueToSecond(Date theDate) throws DataTypeException { 686 if (theDate == null) { 687 setValue((String)null); 688 return; 689 } 690 691 Calendar calendar = Calendar.getInstance(); 692 calendar.setTime(theDate); 693 setValueToSecond(calendar); 694 } 695 696 /** 697 * Returns a string value representing the input Gregorian Calendar object in 698 * an Hl7 TimeStamp Format. 699 */ 700 public static String toHl7TSFormat(GregorianCalendar cal) throws DataTypeException { 701 String val = ""; 702 try { 703 //set the input cal object so that it can report errors 704 //on it's value 705 cal.setLenient(false); 706 int calYear = cal.get(GregorianCalendar.YEAR); 707 int calMonth = cal.get(GregorianCalendar.MONTH) + 1; 708 int calDay = cal.get(GregorianCalendar.DAY_OF_MONTH); 709 int calHour = cal.get(GregorianCalendar.HOUR_OF_DAY); 710 int calMin = cal.get(GregorianCalendar.MINUTE); 711 int calSec = cal.get(GregorianCalendar.SECOND); 712 int calMilli = cal.get(GregorianCalendar.MILLISECOND); 713 //the inputs seconds and milli seconds should be combined into a float type 714 float fractSec = calMilli / 1000F; 715 float calSecFloat = calSec + fractSec; 716 int calOffset = cal.get(GregorianCalendar.ZONE_OFFSET) + cal.get(GregorianCalendar.DST_OFFSET); 717 //Note the input's Offset value is in milliseconds, we must convert it to 718 //a 4 digit integer in the HL7 Offset format. 719 int offSetSignInt; 720 if (calOffset < 0) { 721 offSetSignInt = -1; 722 } 723 else { 724 offSetSignInt = 1; 725 } 726 //get the absolute value of the gmtOffSet 727 int absGmtOffSet = Math.abs(calOffset); 728 int gmtOffSetHours = absGmtOffSet / (3600 * 1000); 729 int gmtOffSetMin = (absGmtOffSet / 60000) % (60); 730 //reset calOffset 731 calOffset = ((gmtOffSetHours * 100) + gmtOffSetMin) * offSetSignInt; 732 //Create an object of the TS class and populate it with the above values 733 //then return the HL7 string value from the object 734 CommonTS ts = new CommonTS(); 735 ts.setDateSecondPrecision(calYear, calMonth, calDay, calHour, calMin, calSecFloat); 736 ts.setOffset(calOffset); 737 val = ts.getValue(); 738 } // end try 739 740 catch (DataTypeException e) { 741 throw e; 742 } //end catch 743 744 catch (Exception e) { 745 throw new DataTypeException(e); 746 } //end catch 747 return val; 748 } //end method 749 750 751 public static void main(String[] args) throws DataTypeException { 752 753 CommonTS ts = new CommonTS(); 754 ts.setValue("1984"); 755 756 System.out.println(ts.getValue()); 757 758 } 759 760 761} //end class