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
027 package ca.uhn.hl7v2.model.primitive;
028
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 * <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")
111 public 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. Passing in <code>null</code> clears any existing value.
406 *
407 * Note: Sets fields using precision up to the millisecond, including timezone offset
408 *
409 * @param theCalendar The calendar object from which to retrieve values
410 * @since 1.1
411 */
412 public void setValue(Calendar theCalendar) throws DataTypeException {
413 if (theCalendar == null) {
414 setValue((String)null);
415 return;
416 }
417
418 int yr = theCalendar.get(Calendar.YEAR);
419 int mnth = theCalendar.get(Calendar.MONTH) + 1;
420 int dy = theCalendar.get(Calendar.DATE);
421 int hr = theCalendar.get(Calendar.HOUR_OF_DAY);
422 int min = theCalendar.get(Calendar.MINUTE);
423 float sec = theCalendar.get(Calendar.SECOND) + (theCalendar.get(Calendar.MILLISECOND) / 1000.0F);
424 setDateSecondPrecision(yr, mnth, dy, hr, min, sec);
425
426 // 3410095: care for integer overflow and timezones not at the full hour, e.g. India
427 int hourOffset= theCalendar.get(Calendar.ZONE_OFFSET) / (1000 * 60 * 60);
428 int minuteOffset = (theCalendar.get(Calendar.ZONE_OFFSET) / (1000 * 60)) % 60;
429 int zoneOffset = hourOffset * 100 + minuteOffset;
430 setOffset(zoneOffset);
431 }
432
433 /**
434 * Convenience setter which sets the value using a {@link Calendar} object. Passing in <code>null</code> clears any existing value.
435 *
436 * Note: Sets fields using precision up to the millisecond, and sets the timezone offset to
437 * the current system offset
438 *
439 * @param theDate The calendar object from which to retrieve values
440 * @since 1.1
441 */
442 public void setValue(Date theDate) throws DataTypeException {
443 if (theDate == null) {
444 setValue((String)null);
445 return;
446 }
447
448 GregorianCalendar cal = new GregorianCalendar();
449 cal.setTime(theDate);
450 setValue(cal);
451 }
452
453 /**
454 * This method takes in a string HL7 Time Stamp value and performs validations.
455 * The stored value will be in the following
456 * format YYYY[MM[DD[HHMM[SS[.S[S[S[S]]]]]]]][+/-ZZZZ].
457 * Note: Trailing zeros supplied in the time value (HHMM[SS[.S[S[S[S]]]]]])
458 * and GMT offset ([+/-ZZZZ]) will be preserved.
459 * Note: If the GMT offset is not supplied then the local
460 * time zone (using standard time zone format which is not modified for daylight savings)
461 * will be stored as a default. Passing in <code>null</code> clears any existing value.
462 */
463 public void setValue(String val) throws DataTypeException {
464 if (val != null && !val.equals("") && !val.equals("\"\"")) {
465 try {
466 //check the length of the input value, ensure that it is no less than
467 //8 characters in length
468 if (val.length() < 4) {
469 String msg = "The length of the TS datatype value must be at least 4 characters in length.";
470 DataTypeException e = new DataTypeException(msg);
471 throw e;
472 }
473
474 //check the length of the input value, ensure that it is not greater
475 //than 24 characters in length
476 if (val.length() > 24) {
477 String msg = "The length of the TS datatype value must not be more than 24 characters in length.";
478 DataTypeException e = new DataTypeException(msg);
479 throw e;
480 }
481
482 //at this point we know that we have a value that should conform to the DT
483 //datatype and possibly a value that should conform to the TM datatype
484 String dateVal = null;
485 String timeVal = null;
486 String timeValLessOffset = null;
487 int sp = val.indexOf("+");
488 int sm = val.indexOf("-");
489 int indexOfSign = -1;
490 boolean offsetExists = false;
491 boolean timeValIsOffsetOnly = false;
492 if ((sp != -1) || (sm != -1)) {
493 offsetExists = true;
494 }
495 if (sp != -1)
496 indexOfSign = sp;
497 if (sm != -1)
498 indexOfSign = sm;
499
500 if (offsetExists == false) {
501 if (val.length() <= 8) {
502 dateVal = val;
503 }
504 else {
505 //here we know that a time value is present
506 dateVal = val.substring(0, 8);
507 timeVal = val.substring(8);
508 timeValLessOffset = timeVal;
509 }
510 } //offset not exist
511
512 if (offsetExists == true) {
513 if (indexOfSign > 8) {
514 dateVal = val.substring(0, 8);
515 timeVal = val.substring(8);
516 timeValLessOffset = val.substring(8, indexOfSign);
517 }
518 else {
519 //we know that the time val is simply the offset
520 dateVal = val.substring(0, indexOfSign);
521 timeVal = val.substring(indexOfSign);
522 timeValIsOffsetOnly = true;
523 }
524 } //offset exists
525
526 //create date object
527 dt = new CommonDT();
528 //set the value of the date object to the input date value
529 dt.setValue(dateVal);
530 //if the offset does not exist and a timvalue does not exist then
531 //we must provide a default offset = to the local time zone
532 if (timeVal == null && offsetExists == false) {
533 // int defaultOffset = DataTypeUtil.getLocalGMTOffset();
534 tm = new CommonTM();
535 //tm.setOffset(defaultOffset);
536 tm.setValue("");
537 } //end if
538
539 //if we have a time value then make a new time object and set it to the
540 //input time value (as long as the time val has time + offset or just time only)
541 if (timeVal != null && timeValIsOffsetOnly == false) {
542 // must make sure that the time component contains both hours
543 // at the very least -- must be at least 2 chars in length.
544 // Note: this changed as of v2.5, before hours AND minutes were required.
545 if (timeValLessOffset.length() < 2) {
546 String msg =
547 "The length of the time component for the TM datatype"
548 + " value does not conform to the allowable format"
549 + " YYYY[MM[DD[HH[MM[SS[.S[S[S[S]]]]]]]]][+/-ZZZZ].";
550 DataTypeException e = new DataTypeException(msg);
551 throw e;
552 } //end if
553 tm = new CommonTM();
554 tm.setValue(timeVal);
555 } //end if
556
557 //if we have a time value and it only has the offset then make a new
558 //time object and set the offset value to the input value
559 if (timeVal != null && timeValIsOffsetOnly == true) {
560 //we know that the time value is just the offset so we
561 //must check to see if it is the right length before setting the
562 //offset field in the tm object
563 if (timeVal.length() != 5) {
564 String msg =
565 "The length of the GMT offset for the TM datatype value does"
566 + " not conform to the allowable format [+/-ZZZZ]";
567 DataTypeException e = new DataTypeException(msg);
568 throw e;
569 } //end if
570 tm = new CommonTM();
571 //first extract the + sign from the offset value string if it exists
572 if (timeVal.indexOf("+") == 0) {
573 timeVal = timeVal.substring(1);
574 } //end if
575 int signedOffset = Integer.parseInt(timeVal);
576 tm.setOffset(signedOffset);
577 } //end if
578 } //end try
579
580 catch (DataTypeException e) {
581 throw e;
582 } //end catch
583
584 catch (Exception e) {
585 throw new DataTypeException(e);
586 } //end catch
587 } //end if
588 else {
589 //set the private value field to null or empty space.
590 if (val == null) {
591 dt = null;
592 tm = null;
593 } //end if
594 if (val != null && val.equals("")) {
595 dt = new CommonDT();
596 dt.setValue("");
597 tm = new CommonTM();
598 tm.setValue("");
599 } //end if
600 if (val != null && val.equals("\"\"")) {
601 dt = new CommonDT();
602 dt.setValue("\"\"");
603 tm = new CommonTM();
604 tm.setValue("\"\"");
605 } //end if
606 } //end else
607
608 } // end method
609
610 /**
611 * Convenience setter which sets the value using a {@link Calendar} object. Passing in <code>null</code> clears any existing value.
612 *
613 * Note: Sets fields using precision up to the minute
614 *
615 * @param theCalendar The calendar object from which to retrieve values
616 * @since 1.1
617 */
618 public void setValueToMinute(Calendar theCalendar) throws DataTypeException {
619 if (theCalendar == null) {
620 setValue((String)null);
621 return;
622 }
623
624 int yr = theCalendar.get(Calendar.YEAR);
625 int mnth = theCalendar.get(Calendar.MONTH) + 1;
626 int dy = theCalendar.get(Calendar.DATE);
627 int hr = theCalendar.get(Calendar.HOUR_OF_DAY);
628 int min = theCalendar.get(Calendar.MINUTE);
629 setDateMinutePrecision(yr, mnth, dy, hr, min);
630
631 }
632
633 /**
634 * Convenience setter which sets the value using a {@link Date} object. Passing in <code>null</code> clears any existing value.
635 *
636 * Note: Sets fields using precision up to the minute
637 *
638 * @param theCalendar The calendar object from which to retrieve values
639 * @since 1.1
640 */
641 public void setValueToMinute(Date theDate) throws DataTypeException {
642 if (theDate == null) {
643 setValue((String)null);
644 return;
645 }
646
647 Calendar calendar = Calendar.getInstance();
648 calendar.setTime(theDate);
649 setValueToMinute(calendar);
650 }
651
652 /**
653 * Convenience setter which sets the value using a {@link Calendar} object. Passing in <code>null</code> clears any existing value.
654 *
655 * Note: Sets fields using precision up to the second
656 *
657 * @param theCalendar The calendar object from which to retrieve values
658 * @since 1.1
659 */
660 public void setValueToSecond(Calendar theCalendar) throws DataTypeException {
661 if (theCalendar == null) {
662 setValue((String)null);
663 return;
664 }
665
666 int yr = theCalendar.get(Calendar.YEAR);
667 int mnth = theCalendar.get(Calendar.MONTH) + 1;
668 int dy = theCalendar.get(Calendar.DATE);
669 int hr = theCalendar.get(Calendar.HOUR_OF_DAY);
670 int min = theCalendar.get(Calendar.MINUTE);
671 int sec = theCalendar.get(Calendar.SECOND);
672 setDateSecondPrecision(yr, mnth, dy, hr, min, sec);
673 }
674
675 /**
676 * Convenience setter which sets the value using a {@link Date} object. Passing in <code>null</code> clears any existing value.
677 *
678 * Note: Sets fields using precision up to the second
679 *
680 * @param theCalendar The calendar object from which to retrieve values
681 * @since 1.1
682 */
683 public void setValueToSecond(Date theDate) throws DataTypeException {
684 if (theDate == null) {
685 setValue((String)null);
686 return;
687 }
688
689 Calendar calendar = Calendar.getInstance();
690 calendar.setTime(theDate);
691 setValueToSecond(calendar);
692 }
693
694 /**
695 * Returns a string value representing the input Gregorian Calendar object in
696 * an Hl7 TimeStamp Format.
697 */
698 public static String toHl7TSFormat(GregorianCalendar cal) throws DataTypeException {
699 String val = "";
700 try {
701 //set the input cal object so that it can report errors
702 //on it's value
703 cal.setLenient(false);
704 int calYear = cal.get(GregorianCalendar.YEAR);
705 int calMonth = cal.get(GregorianCalendar.MONTH) + 1;
706 int calDay = cal.get(GregorianCalendar.DAY_OF_MONTH);
707 int calHour = cal.get(GregorianCalendar.HOUR_OF_DAY);
708 int calMin = cal.get(GregorianCalendar.MINUTE);
709 int calSec = cal.get(GregorianCalendar.SECOND);
710 int calMilli = cal.get(GregorianCalendar.MILLISECOND);
711 //the inputs seconds and milli seconds should be combined into a float type
712 float fractSec = calMilli / 1000F;
713 float calSecFloat = calSec + fractSec;
714 int calOffset = cal.get(GregorianCalendar.ZONE_OFFSET);
715 //Note the input's Offset value is in milliseconds, we must convert it to
716 //a 4 digit integer in the HL7 Offset format.
717 int offSetSignInt;
718 if (calOffset < 0) {
719 offSetSignInt = -1;
720 }
721 else {
722 offSetSignInt = 1;
723 }
724 //get the absolute value of the gmtOffSet
725 int absGmtOffSet = Math.abs(calOffset);
726 int gmtOffSetHours = absGmtOffSet / (3600 * 1000);
727 int gmtOffSetMin = (absGmtOffSet / 60000) % (60);
728 //reset calOffset
729 calOffset = ((gmtOffSetHours * 100) + gmtOffSetMin) * offSetSignInt;
730 //Create an object of the TS class and populate it with the above values
731 //then return the HL7 string value from the object
732 CommonTS ts = new CommonTS();
733 ts.setDateSecondPrecision(calYear, calMonth, calDay, calHour, calMin, calSecFloat);
734 ts.setOffset(calOffset);
735 val = ts.getValue();
736 } // end try
737
738 catch (DataTypeException e) {
739 throw e;
740 } //end catch
741
742 catch (Exception e) {
743 throw new DataTypeException(e);
744 } //end catch
745 return val;
746 } //end method
747
748
749 public static void main(String[] args) throws DataTypeException {
750
751 CommonTS ts = new CommonTS();
752 ts.setValue("1984");
753
754 System.out.println(ts.getValue());
755
756 }
757
758
759 } //end class