Coverage Report - ca.uhn.hl7v2.model.primitive.CommonTS
 
Classes in this File Line Coverage Branch Coverage Complexity
CommonTS
87%
239/273
80%
96/120
4.692
 
 1  
 /**
 2  
  * The contents of this file are subject to the Mozilla Public License Version 1.1
 3  
  * (the "License"); you may not use this file except in compliance with the License.
 4  
  * You may obtain a copy of the License at http://www.mozilla.org/MPL/
 5  
  * Software distributed under the License is distributed on an "AS IS" basis,
 6  
  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License for the
 7  
  * specific language governing rights and limitations under the License.
 8  
  *
 9  
  *
 10  
  *
 11  
  * The Initial Developer of the Original Code is University Health Network. Copyright (C)
 12  
  * 2001.  All Rights Reserved.
 13  
  *
 14  
  * Contributor(s): ______________________________________.
 15  
  *
 16  
  * Alternatively, the contents of this file may be used under the terms of the
 17  
  * GNU General Public License (the "GPL"), in which case the provisions of the GPL are
 18  
  * applicable instead of those above.  If you wish to allow use of your version of this
 19  
  * file only under the terms of the GPL and not to allow others to use your version
 20  
  * of this file under the MPL, indicate your decision by deleting  the provisions above
 21  
  * and replace  them with the notice and other provisions required by the GPL License.
 22  
  * If you do not delete the provisions above, a recipient may use your version of
 23  
  * this file under either the MPL or the GPL.
 24  
  *
 25  
  */
 26  
 
 27  
 package ca.uhn.hl7v2.model.primitive;
 28  
 
 29  
 import ca.uhn.hl7v2.model.DataTypeException;
 30  
 import ca.uhn.hl7v2.model.DataTypeUtil;
 31  
 
 32  
 import java.io.Serializable;
 33  
 import java.util.Calendar;
 34  
 import java.util.Date;
 35  
 import java.util.GregorianCalendar;
 36  
 
 37  
 /**
 38  
  * <p>
 39  
  * This class contains functionality used by the TS class
 40  
  * in the version 2.3.0, 2.3.1, and 2.4 packages
 41  
  * </p>
 42  
  * 
 43  
  * <p>
 44  
  * Note: The class description below has been excerpted from the Hl7 2.4 documentation. Sectional
 45  
  * references made below also refer to the same documentation.
 46  
  * </p>
 47  
  *
 48  
  * <p>
 49  
  * Format: YYYY[MM[DD[HHMM[SS[.S[S[S[S]]]]]]]][+/-ZZZZ]^<degree of precision>
 50  
  * </p>
 51  
  * 
 52  
  * <p>
 53  
  * Contains the exact time of an event, including the date and time. The date portion of a time stamp follows the rules of a
 54  
  * date field and the time portion follows the rules of a time field. The time zone (+/-ZZZZ) is represented as +/-HHMM
 55  
  * offset from UTC (formerly Greenwich Mean Time (GMT)), where +0000 or -0000 both represent UTC (without offset).
 56  
  * The specific data representations used in the HL7 encoding rules are compatible with ISO 8824-1987(E).
 57  
  * In prior versions of HL7, an optional second component indicates the degree of precision of the time stamp (Y = year, L
 58  
  * = month, D = day, H = hour, M = minute, S = second). This optional second component is retained only for purposes of
 59  
  * backward compatibility.
 60  
  * </p>
 61  
  * 
 62  
  * <p>
 63  
  * By site-specific agreement, YYYYMMDD[HHMM[SS[.S[S[S[S]]]]]][+/-ZZZZ]^<degree of precision> may be used
 64  
  * where backward compatibility must be maintained.
 65  
  * In the current and future versions of HL7, the precision is indicated by limiting the number of digits used, unless the
 66  
  * optional second component is present. Thus, YYYY is used to specify a precision of "year," YYYYMM specifies a
 67  
  * precision of "month," YYYYMMDD specifies a precision of "day," YYYYMMDDHH is used to specify a precision of
 68  
  * "hour," YYYYMMDDHHMM is used to specify a precision of "minute," YYYYMMDDHHMMSS is used to specify a
 69  
  * precision of seconds, and YYYYMMDDHHMMSS.SSSS is used to specify a precision of ten thousandths of a second.
 70  
  * In each of these cases, the time zone is an optional component. Note that if the time zone is not included, the timezone
 71  
  * 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"
 72  
  * represents midnight of the night extending from the previous day to the day given by the YYYYMMDD part (see example
 73  
  * below). Maximum length of the time stamp is 26. 
 74  
  * </p>
 75  
  * <p>
 76  
  * Examples: <br/>
 77  
  * |19760704010159-0500|<br/>
 78  
  * 1:01:59 on July 4, 1976 in the Eastern Standard Time zone (USA).<br/>
 79  
  * |19760704010159-0400|<br/>
 80  
  * 1:01:59 on July 4, 1976 in the Eastern Daylight Saving Time zone (USA).<br/>
 81  
  * |198807050000|<br/>
 82  
  * Midnight of the night extending from July 4 to July 5, 1988 in the local time zone of the sender.<br/>
 83  
  * |19880705|<br/>
 84  
  * Same as prior example, but precision extends only to the day. Could be used for a birthdate, if the time of birth is
 85  
  * unknown.<br/>
 86  
  * |19981004010159+0100|<br/>
 87  
  * 1:01:59 on October 4, 1998 in Amsterdam, NL. (Time zone=+0100).<br/>
 88  
  * </p>
 89  
  * <p>
 90  
  * The HL7 Standard strongly recommends that all systems routinely send the time zone offset but does not require it. All
 91  
  * HL7 systems are required to accept the time zone offset, but its implementation is application specific. For many
 92  
  * applications the time of interest is the local time of the sender. For example, an application in the Eastern Standard Time
 93  
  * zone receiving notification of an admission that takes place at 11:00 PM in San Francisco on December 11 would prefer
 94  
  * to treat the admission as having occurred on December 11 rather than advancing the date to December 12.
 95  
  * </p>
 96  
  * <p>
 97  
  * Note: The time zone [+/-ZZZZ], when used, is restricted to legally-defined time zones and is represented in HHMM
 98  
  * format.
 99  
  * </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  3913
     public CommonTS() {
 121  3913
     } //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  345
     public CommonTS(String val) throws DataTypeException {
 129  345
         this.setValue(val);
 130  345
     } //end constructor
 131  
 
 132  
     /**
 133  
      * Returns the day as an integer.
 134  
      */
 135  
     public int getDay() {
 136  1440
         int day = 0;
 137  1440
         if (dt != null) {
 138  1440
             day = dt.getDay();
 139  
         } //end if
 140  1440
         return day;
 141  
     } //end method
 142  
 
 143  
     /**
 144  
      * Returns the fractional second value as a float.
 145  
      */
 146  
     public float getFractSecond() {
 147  545
         float fractionOfSec = 0;
 148  545
         if (tm != null) {
 149  545
             fractionOfSec = tm.getFractSecond();
 150  
         } //end if
 151  545
         return fractionOfSec;
 152  
     } //end method
 153  
 
 154  
     /**
 155  
      * Returns the GMT offset value as an integer.
 156  
      */
 157  
     public int getGMTOffset() {
 158  550
         int offSet = 0;
 159  550
         if (tm != null) {
 160  550
                 offSet = tm.getGMTOffset();
 161  
         } //end if
 162  550
         return offSet;
 163  
     } //end method
 164  
 
 165  
     /**
 166  
      * Returns the hour as an integer.
 167  
      */
 168  
     public int getHour() {
 169  545
         int hour = 0;
 170  545
         if (tm != null) {
 171  545
             hour = tm.getHour();
 172  
         } //end if
 173  545
         return hour;
 174  
     } //end method
 175  
 
 176  
     /**
 177  
      * Returns the minute as an integer.
 178  
      */
 179  
     public int getMinute() {
 180  545
         int minute = 0;
 181  545
         if (tm != null) {
 182  545
             minute = tm.getMinute();
 183  
         } //end if
 184  545
         return minute;
 185  
     } //end method
 186  
 
 187  
     /**
 188  
      * Returns the month as an integer.
 189  
      */
 190  
     public int getMonth() {
 191  1440
         int month = 0;
 192  1440
         if (dt != null) {
 193  1440
             month = dt.getMonth();
 194  
         } //end if
 195  1440
         return month;
 196  
     } //end method
 197  
 
 198  
     /**
 199  
      * Returns the second as an integer.
 200  
      */
 201  
     public int getSecond() {
 202  545
         int seconds = 0;
 203  545
         if (tm != null) {
 204  545
             seconds = tm.getSecond();
 205  
         } //end if
 206  545
         return seconds;
 207  
     } //end method
 208  
 
 209  
     /**
 210  
      * Returns the HL7 TS string value.
 211  
      */
 212  
     public String getValue() {
 213  3723
         String value = null;
 214  3723
         if (dt != null) {
 215  3703
             value = dt.getValue();
 216  
         } //end if
 217  3723
         if (tm != null && value != null && !value.equals("")) {
 218  3648
             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  3523
                 if (tm.getValue().equals("\"\"") && dt.getValue().equals("\"\"")) {
 221  
                     //set value to the delete value ("")
 222  5
                     value = "\"\"";
 223  
                 }
 224  
                 else{
 225  
                     //set value to date concatonated with time value
 226  3518
                     value = value + tm.getValue();
 227  
                 }                
 228  
             } //end if
 229  3648
             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  125
                 int offset = tm.getGMTOffset();
 233  125
                 String offsetStr = "";
 234  125
                 if (offset != CommonTM.GMT_OFFSET_NOT_SET_VALUE) {
 235  90
                     offsetStr = DataTypeUtil.preAppendZeroes(Math.abs(offset), 4);
 236  90
                     if (tm.getGMTOffset() >= 0) {
 237  60
                         offsetStr = "+" + offsetStr;
 238  
                     } //end if
 239  
                     else {
 240  30
                         offsetStr = "-" + offsetStr;
 241  
                     } //end else
 242  
                 }
 243  125
                 value = value + offsetStr;
 244  
             } //end if
 245  
         } //end if
 246  3723
         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  900
             if (getValue() == null) {
 257  5
                     return null;
 258  
             }
 259  
             
 260  895
         Calendar retVal = tm.getValueAsCalendar();
 261  
 
 262  895
         retVal.set(Calendar.YEAR, getYear());
 263  895
         retVal.set(Calendar.MONTH, getMonth() - 1);
 264  895
         retVal.set(Calendar.DATE, getDay());
 265  
         
 266  895
         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  325
             if (getValue() == null) {
 277  5
                     return null;
 278  
             }
 279  
 
 280  320
             return getValueAsCalendar().getTime();
 281  
     }
 282  
     
 283  
     /**
 284  
      * Returns the year as an integer.
 285  
      */
 286  
     public int getYear() {
 287  1440
         int year = 0;
 288  1440
         if (dt != null) {
 289  1440
             year = dt.getYear();
 290  
         } //end if
 291  1440
         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  165
             this.setDatePrecision(yr, mnth, dy);
 304  
             //create new time object is there isn't one
 305  110
             if (tm == null) {
 306  110
                 tm = new CommonTM();
 307  
             }
 308  
             //set the value of the time object to the minute precision with the input values
 309  110
             tm.setHourMinutePrecision(hr, min);
 310  
         } //end try
 311  
 
 312  80
         catch (DataTypeException e) {
 313  80
             throw e;
 314  
         } //end catch
 315  
 
 316  0
         catch (Exception e) {
 317  0
             throw new DataTypeException(e);
 318  85
         } //end catch
 319  85
     } //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  3518
             if (dt == null) {
 332  3518
                 dt = new CommonDT();
 333  
             }
 334  
             //set the value of the date object to the input date value
 335  3518
             dt.setYearMonthDayPrecision(yr, mnth, dy);
 336  
             //clear the time value object
 337  3358
             tm = null;
 338  
         } //end try
 339  
 
 340  160
         catch (DataTypeException e) {
 341  160
             throw e;
 342  
         } //end catch
 343  
 
 344  0
         catch (Exception e) {
 345  0
             throw new DataTypeException(e);
 346  3358
         } //end catch
 347  3358
     } //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  3248
             this.setDatePrecision(yr, mnth, dy);
 364  
             //create new time object is there isn't one
 365  3198
             if (tm == null) {
 366  3198
                 tm = new CommonTM();
 367  
             }
 368  
             //set the value of the time object to the second precision with the input values
 369  3198
             tm.setHourMinSecondPrecision(hr, min, sec);
 370  
         } //end try
 371  
 
 372  95
         catch (DataTypeException e) {
 373  95
             throw e;
 374  
         } //end catch
 375  
 
 376  0
         catch (Exception e) {
 377  0
             throw new DataTypeException(e);
 378  3153
         } //end catch
 379  3153
     } //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  3078
             if (tm == null) {
 389  0
                 tm = new CommonTM();
 390  
             }
 391  
             //set the offset value of the time object to the input value
 392  3078
             tm.setOffset(signedOffset);
 393  
         }
 394  
 
 395  10
         catch (DataTypeException e) {
 396  10
             throw e;
 397  
         } //end catch
 398  
 
 399  0
         catch (Exception e) {
 400  0
             throw new DataTypeException(e);
 401  3068
         } //end catch
 402  3068
     } //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  1590
                 if (theCalendar == null) {
 415  0
                         setValue((String)null);
 416  0
                         return;
 417  
                 }
 418  
 
 419  1590
                 int yr = theCalendar.get(Calendar.YEAR);
 420  1590
         int mnth = theCalendar.get(Calendar.MONTH) + 1;
 421  1590
         int dy = theCalendar.get(Calendar.DATE);
 422  1590
         int hr = theCalendar.get(Calendar.HOUR_OF_DAY);
 423  1590
         int min = theCalendar.get(Calendar.MINUTE);
 424  1590
         float sec = theCalendar.get(Calendar.SECOND) + (theCalendar.get(Calendar.MILLISECOND) / 1000.0F);
 425  1590
         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  1590
         int timeZoneOffset = theCalendar.get(Calendar.ZONE_OFFSET) + theCalendar.get(Calendar.DST_OFFSET);
 429  1590
         int hourOffset= timeZoneOffset / (1000 * 60 * 60);   
 430  1590
         int minuteOffset = (timeZoneOffset / (1000 * 60)) % 60;
 431  1590
         int zoneOffset = hourOffset * 100 + minuteOffset;
 432  1590
         setOffset(zoneOffset);
 433  1590
     }
 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  205
                 if (theDate == null) {
 446  0
                         setValue((String)null);
 447  0
                         return;
 448  
                 }
 449  
 
 450  205
                 GregorianCalendar cal = new GregorianCalendar();
 451  205
                 cal.setTime(theDate);
 452  205
                 setValue(cal);
 453  205
         }
 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  965
         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  710
                 if (val.length() < 4) {
 471  20
                     String msg = "The length of the TS datatype value must be at least 4 characters in length.";
 472  20
                     DataTypeException e = new DataTypeException(msg);
 473  20
                     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  690
                 if (val.length() > 24) {
 479  0
                     String msg = "The length of the TS datatype value must not be more than 24 characters in length.";
 480  0
                     DataTypeException e = new DataTypeException(msg);
 481  0
                     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  690
                 String dateVal = null;
 487  690
                 String timeVal = null;
 488  690
                 String timeValLessOffset = null;
 489  690
                 int sp = val.indexOf("+");
 490  690
                 int sm = val.indexOf("-");
 491  690
                 int indexOfSign = -1;
 492  690
                 boolean offsetExists = false;
 493  690
                 boolean timeValIsOffsetOnly = false;
 494  690
                 if ((sp != -1) || (sm != -1)) {
 495  485
                     offsetExists = true;
 496  
                 }
 497  690
                 if (sp != -1)
 498  170
                     indexOfSign = sp;
 499  690
                 if (sm != -1)
 500  315
                     indexOfSign = sm;
 501  
 
 502  690
                 if (!offsetExists) {
 503  205
                     if (val.length() <= 8) {
 504  60
                         dateVal = val;
 505  
                     }
 506  
                     else {
 507  
                         //here we know that a time value is present
 508  145
                         dateVal = val.substring(0, 8);
 509  145
                         timeVal = val.substring(8);
 510  145
                         timeValLessOffset = timeVal;
 511  
                     }
 512  
                 } //offset not exist
 513  
 
 514  690
                 if (offsetExists) {
 515  485
                     if (indexOfSign > 8) {
 516  300
                         dateVal = val.substring(0, 8);
 517  300
                         timeVal = val.substring(8);
 518  300
                         timeValLessOffset = val.substring(8, indexOfSign);
 519  
                     }
 520  
                     else {
 521  
                         //we know that the time val is simply the offset
 522  185
                         dateVal = val.substring(0, indexOfSign);
 523  185
                         timeVal = val.substring(indexOfSign);
 524  185
                         timeValIsOffsetOnly = true;
 525  
                     }
 526  
                 } //offset exists
 527  
 
 528  
                 //create date object
 529  690
                 dt = new CommonDT();
 530  
                 //set the value of the date object to the input date value
 531  690
                 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  660
                 if (timeVal == null && !offsetExists) {
 535  
 //                    int defaultOffset = DataTypeUtil.getLocalGMTOffset();
 536  30
                     tm = new CommonTM();
 537  
                     //tm.setOffset(defaultOffset);
 538  30
                     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  660
                 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  445
                     if (timeValLessOffset.length() < 2) {
 548  5
                         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  5
                         DataTypeException e = new DataTypeException(msg);
 553  5
                         throw e;
 554  
                     } //end if
 555  440
                     tm = new CommonTM();
 556  440
                     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  520
                 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  185
                     if (timeVal.length() != 5) {
 566  60
                         String msg =
 567  
                             "The length of the GMT offset for the TM datatype value does"
 568  
                                 + " not conform to the allowable format [+/-ZZZZ]";
 569  60
                         DataTypeException e = new DataTypeException(msg);
 570  60
                         throw e;
 571  
                     } //end if 
 572  125
                     tm = new CommonTM();
 573  
                     //first extract the + sign from the offset value string if it exists
 574  125
                     if (timeVal.indexOf("+") == 0) {
 575  65
                         timeVal = timeVal.substring(1);
 576  
                     } //end if
 577  125
                     int signedOffset = Integer.parseInt(timeVal);
 578  125
                     tm.setOffset(signedOffset);
 579  
                 } //end if
 580  
             } //end try
 581  
 
 582  280
             catch (DataTypeException e) {
 583  280
                 throw e;
 584  
             } //end catch
 585  
 
 586  0
             catch (Exception e) {
 587  0
                 throw new DataTypeException(e);
 588  430
             } //end catch
 589  
         } //end if
 590  
         else {
 591  
             //set the private value field to null or empty space.
 592  255
             if (val == null) {
 593  240
                 dt = null;
 594  240
                 tm = null;
 595  
             } //end if
 596  255
             if (val != null && val.equals("")) {
 597  5
                 dt = new CommonDT();
 598  5
                 dt.setValue("");
 599  5
                 tm = new CommonTM();
 600  5
                 tm.setValue("");
 601  
             } //end if
 602  255
             if (val != null && val.equals("\"\"")) {
 603  10
                 dt = new CommonDT();
 604  10
                 dt.setValue("\"\"");
 605  10
                 tm = new CommonTM();
 606  10
                 tm.setValue("\"\"");
 607  
             } //end if
 608  
         } //end else    
 609  
 
 610  685
     } // 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  25
                 if (theCalendar == null) {
 622  0
                         setValue((String)null);
 623  0
                         return;
 624  
                 }
 625  
 
 626  25
             int yr = theCalendar.get(Calendar.YEAR);
 627  25
         int mnth = theCalendar.get(Calendar.MONTH) + 1;
 628  25
         int dy = theCalendar.get(Calendar.DATE);
 629  25
         int hr = theCalendar.get(Calendar.HOUR_OF_DAY);
 630  25
         int min = theCalendar.get(Calendar.MINUTE);
 631  25
         setDateMinutePrecision(yr, mnth, dy, hr, min);
 632  
         
 633  25
     }
 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  15
                 if (theDate == null) {
 645  0
                         setValue((String)null);
 646  0
                         return;
 647  
                 }
 648  
 
 649  15
                 Calendar calendar = Calendar.getInstance();
 650  15
         calendar.setTime(theDate);
 651  15
         setValueToMinute(calendar);
 652  15
     }
 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  20
                 if (theCalendar == null) {
 664  0
                         setValue((String)null);
 665  0
                         return;
 666  
                 }
 667  
 
 668  20
         int yr = theCalendar.get(Calendar.YEAR);
 669  20
         int mnth = theCalendar.get(Calendar.MONTH) + 1;
 670  20
         int dy = theCalendar.get(Calendar.DATE);
 671  20
         int hr = theCalendar.get(Calendar.HOUR_OF_DAY);
 672  20
         int min = theCalendar.get(Calendar.MINUTE);
 673  20
         int sec = theCalendar.get(Calendar.SECOND);
 674  20
         setDateSecondPrecision(yr, mnth, dy, hr, min, sec);
 675  20
     }
 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  10
                 if (theDate == null) {
 687  0
                         setValue((String)null);
 688  0
                         return;
 689  
                 }
 690  
 
 691  10
                 Calendar calendar = Calendar.getInstance();
 692  10
         calendar.setTime(theDate);
 693  10
         setValueToSecond(calendar);
 694  10
     }
 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  1443
         String val = "";
 702  
         try {
 703  
             //set the input cal object so that it can report errors
 704  
             //on it's value
 705  1443
             cal.setLenient(false);
 706  1443
             int calYear = cal.get(GregorianCalendar.YEAR);
 707  1443
             int calMonth = cal.get(GregorianCalendar.MONTH) + 1;
 708  1443
             int calDay = cal.get(GregorianCalendar.DAY_OF_MONTH);
 709  1443
             int calHour = cal.get(GregorianCalendar.HOUR_OF_DAY);
 710  1443
             int calMin = cal.get(GregorianCalendar.MINUTE);
 711  1443
             int calSec = cal.get(GregorianCalendar.SECOND);
 712  1443
             int calMilli = cal.get(GregorianCalendar.MILLISECOND);
 713  
             //the inputs seconds and milli seconds should be combined into a float type
 714  1443
             float fractSec = calMilli / 1000F;
 715  1443
             float calSecFloat = calSec + fractSec;
 716  1443
             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  1443
             if (calOffset < 0) {
 721  1433
                 offSetSignInt = -1;
 722  
             }
 723  
             else {
 724  10
                 offSetSignInt = 1;
 725  
             }
 726  
             //get the absolute value of the gmtOffSet
 727  1443
             int absGmtOffSet = Math.abs(calOffset);
 728  1443
             int gmtOffSetHours = absGmtOffSet / (3600 * 1000);
 729  1443
             int gmtOffSetMin = (absGmtOffSet / 60000) % (60);
 730  
             //reset calOffset
 731  1443
             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  1443
             CommonTS ts = new CommonTS();
 735  1443
             ts.setDateSecondPrecision(calYear, calMonth, calDay, calHour, calMin, calSecFloat);
 736  1443
             ts.setOffset(calOffset);
 737  1443
             val = ts.getValue();
 738  
         } // end try
 739  
 
 740  0
         catch (DataTypeException e) {
 741  0
             throw e;
 742  
         } //end catch
 743  
 
 744  0
         catch (Exception e) {
 745  0
             throw new DataTypeException(e);
 746  1443
         } //end catch
 747  1443
         return val;
 748  
     } //end method
 749  
 
 750  
     
 751  
     public static void main(String[] args) throws DataTypeException {
 752  
             
 753  0
             CommonTS ts = new CommonTS();
 754  0
             ts.setValue("1984");
 755  
             
 756  0
             System.out.println(ts.getValue());
 757  
             
 758  0
     }
 759  
     
 760  
     
 761  
 } //end class