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 "CommmonTM.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; 029 030import java.util.Calendar; 031import java.util.Date; 032import java.util.GregorianCalendar; 033import java.util.TimeZone; 034import java.io.Serializable; 035 036import ca.uhn.hl7v2.model.DataTypeException; 037import ca.uhn.hl7v2.model.DataTypeUtil; 038 039/** 040 * This class contains functionality used by the TM class 041 * in the version 2.3.0, 2.3.1, and 2.4 packages 042 * 043 * Note: The class description below has been excerpted from the Hl7 2.4 documentation. Sectional 044 * references made below also refer to the same documentation. 045 * 046 * Format: HH[MM[SS[.S[S[S[S]]]]]][+/-ZZZZ] 047 * In prior versions of HL7, this data type was always specified to be in the 048 * format HHMM[SS[.SSSS]][+/-ZZZZ] using a 24 hour clock notation. In the 049 * current and future versions, the precision of a time may be expressed by 050 * limiting the number of digits used with the format specification as shown 051 * above. By site-specific agreement, HHMM[SS[.SSSS]][+/-ZZZZ] may be used where 052 * backward compatibility must be maintained. 053 * Thus, HH is used to specify a precision of "hour," HHMM is used to specify a 054 * precision of "minute," HHMMSS is used to specify a precision of seconds, and 055 * HHMMSS.SSSS is used to specify a precision of ten-thousandths of a second. 056 * In each of these cases, the time zone is an optional component. The fractional 057 * seconds could be sent by a transmitter who requires greater precision than whole 058 * seconds. Fractional representations of minutes, hours or other higher-order units 059 * of time are not permitted. 060 * Note: The time zone [+/-ZZZZ], when used, is restricted to legally-defined time zones 061 * and is represented in HHMM format. 062 * The time zone of the sender may be sent optionally as an offset from the coordinated 063 * universal time (previously known as Greenwich Mean Time). Where the time zone 064 * is not present in a particular TM field but is included as part of the date/time 065 * field in the MSH segment, the MSH value will be used as the default time zone. 066 * Otherwise, the time is understood to refer to the local time of the sender. 067 * Midnight is represented as 0000. 068 * Examples:|235959+1100| 1 second before midnight in a time zone eleven hours 069 * ahead of Universal Coordinated Time (i.e., east of Greenwich). 070 * |0800| Eight AM, local time of the sender. 071 * |093544.2312| 44.2312 seconds after Nine thirty-five AM, local time of sender. 072 * |13| 1pm (with a precision of hours), local time of sender. 073 * @author Neal Acharya 074 */ 075 076@SuppressWarnings("serial") 077public class CommonTM implements Serializable { 078 079 /** 080 * Value returned by {@link #getGMTOffset()} if no offset is set 081 */ 082 public static final int GMT_OFFSET_NOT_SET_VALUE = -99; 083 084 private String value; 085 private int hour; 086 private int minute; 087 private int second; 088 private float fractionOfSec; 089 private int offSet; 090 private boolean omitOffsetFg = false; 091 092 /** 093 * Constructs a TM datatype with fields initialzed to zero and the value set to 094 * null. 095 */ 096 public CommonTM() { 097 //initialize all DT fields 098 value = null; 099 hour = 0; 100 minute = 0; 101 second = 0; 102 fractionOfSec = 0; 103 offSet = GMT_OFFSET_NOT_SET_VALUE; 104 } //end constructor 105 106 /** 107 * Constructs a TM object with the given value. 108 * The stored value will be in the following 109 * format HH[MM[SS[.S[S[S[S]]]]]][+/-ZZZZ]. 110 */ 111 public CommonTM(String val) throws DataTypeException { 112 this.setValue(val); 113 } //end constructor 114 115 /** 116 * This method takes in a string HL7 Time value and performs validations 117 * then sets the value field. The stored value will be in the following 118 * format HH[MM[SS[.S[S[S[S]]]]]][+/-ZZZZ]. 119 * Note: Trailing zeros supplied in the time value (HH[MM[SS[.S[S[S[S]]]]]]) 120 * and GMT offset ([+/-ZZZZ]) will be preserved. 121 * Note: If the GMT offset is not supplied then the local 122 * time zone (using standard time zone format which is not modified for daylight savings) 123 * will be stored as a default. Passing in <code>null</code> clears any existing value. 124 */ 125 public void setValue(String val) throws DataTypeException { 126 127 if (val != null && !val.equals("") && !val.equals("\"\"")) { 128 //check to see if any of the following characters exist: "." or "+/-" 129 //this will help us determine the acceptable lengths 130 131 int d = val.indexOf("."); 132 int sp = val.indexOf("+"); 133 int sm = val.indexOf("-"); 134 int indexOfSign = -1; 135 boolean offsetExists = false; 136 if ((sp != -1) || (sm != -1)) 137 offsetExists = true; 138 if (sp != -1) 139 indexOfSign = sp; 140 if (sm != -1) 141 indexOfSign = sm; 142 143 try { 144 //If the GMT offset exists then extract it from the input string and store it 145 //in another variable called tempOffset. Also, store the time value 146 //(without the offset)in a separate variable called timeVal. 147 //If there is no GMT offset then simply set timeVal to val. 148 String timeVal = val; 149 String tempOffset = null; 150 if (offsetExists) { 151 timeVal = val.substring(0, indexOfSign); 152 tempOffset = val.substring(indexOfSign); 153 } //end if 154 155 if (offsetExists && (tempOffset.length() != 5)) { 156 //The length of the GMT offset must be 5 characters (including the sign) 157 String msg = 158 "The length of the TM datatype value does not conform to an allowable" 159 + " format. Format should conform to HH[MM[SS[.S[S[S[S]]]]]][+/-ZZZZ]"; 160 throw new DataTypeException(msg); 161 } //end if 162 163 if (d != -1) { 164 //here we know that decimal exists 165 //thus length of the time value can be between 8 and 11 characters 166 if ((timeVal.length() < 8) || (timeVal.length() > 11)) { 167 String msg = 168 "The length of the TM datatype value does not conform to an allowable" 169 + " format. Format should conform to HH[MM[SS[.S[S[S[S]]]]]][+/-ZZZZ]"; 170 throw new DataTypeException(msg); 171 } //end if 172 } //end if 173 174 if (d == -1) { 175 //here we know that the decimal does not exist 176 //thus length of the time value can be 2 or 4 or 6 characters 177 if ((timeVal.length() != 2) && (timeVal.length() != 4) && (timeVal.length() != 6)) { 178 String msg = 179 "The length of the TM datatype value does not conform to an allowable" 180 + " format. Format should conform to HH[MM[SS[.S[S[S[S]]]]]][+/-ZZZZ]"; 181 throw new DataTypeException(msg); 182 } //end if 183 } //end if 184 185 //We will now try to validate the timeVal portion of the TM datatype value 186 if (timeVal.length() >= 2) { 187 //extract the hour data from the input value. If the first 2 characters 188 //are not numeric then a number format exception will be generated 189 int hrInt = Integer.parseInt(timeVal.substring(0, 2)); 190 //check to see if the hour value is valid 191 if ((hrInt < 0) || (hrInt > 23)) { 192 String msg = "The hour value of the TM datatype must be >=0 and <=23"; 193 throw new DataTypeException(msg); 194 } //end if 195 hour = hrInt; 196 } //end if 197 198 if (timeVal.length() >= 4) { 199 //extract the minute data from the input value 200 //If these characters are not numeric then a number 201 //format exception will be generated 202 int minInt = Integer.parseInt(timeVal.substring(2, 4)); 203 //check to see if the minute value is valid 204 if ((minInt < 0) || (minInt > 59)) { 205 String msg = "The minute value of the TM datatype must be >=0 and <=59"; 206 throw new DataTypeException(msg); 207 } //end if 208 minute = minInt; 209 } //end if 210 211 if (timeVal.length() >= 6) { 212 //extract the seconds data from the input value 213 //If these characters are not numeric then a number 214 //format exception will be generated 215 int secInt = Integer.parseInt(timeVal.substring(4, 6)); 216 //check to see if the seconds value is valid 217 if ((secInt < 0) || (secInt > 59)) { 218 String msg = "The seconds value of the TM datatype must be >=0 and <=59"; 219 throw new DataTypeException(msg); 220 } //end if 221 second = secInt; 222 } //end if 223 224 if (timeVal.length() >= 8) { 225 //extract the fractional second value from the input value 226 //If these characters are not numeric then a number 227 //format exception will be generated 228 float fract = Float.parseFloat(timeVal.substring(6)); 229 //check to see if the fractional second value is valid 230 if ((fract < 0) || (fract >= 1)) { 231 String msg = "The fractional second value of the TM datatype must be >= 0 and < 1"; 232 throw new DataTypeException(msg); 233 } //end if 234 fractionOfSec = fract; 235 } //end if 236 237 //We will now try to validate the tempOffset portion of the TM datatype value 238 if (offsetExists) { 239 //in case the offset are a series of zeros we should not omit displaying 240 //it in the return value from the getValue() method 241 omitOffsetFg = false; 242 //remove the sign from the temp offset 243 String tempOffsetNoS = tempOffset.substring(1); 244 //extract the hour data from the offset value. If the first 2 characters 245 //are not numeric then a number format exception will be generated 246 int offsetInt = Integer.parseInt(tempOffsetNoS.substring(0, 2)); 247 //check to see if the hour value is valid 248 if ((offsetInt < 0) || (offsetInt > 23)) { 249 String msg = "The GMT offset hour value of the TM datatype must be >=0 and <=23"; 250 throw new DataTypeException(msg); 251 } //end if 252 //extract the minute data from the offset value. If these characters 253 //are not numeric then a number format exception will be generated 254 offsetInt = Integer.parseInt(tempOffsetNoS.substring(2, 4)); 255 //check to see if the minute value is valid 256 if ((offsetInt < 0) || (offsetInt > 59)) { 257 String msg = "The GMT offset minute value of the TM datatype must be >=0 and <=59"; 258 throw new DataTypeException(msg); 259 } //end if 260 //validation done, update the offSet field 261 offSet = Integer.parseInt(tempOffsetNoS); 262 //add the sign back to the offset if it is negative 263 if (sm != -1) { 264 offSet = -1 * offSet; 265 } //end if 266 } //end if 267 268 //If the GMT offset has not been supplied then set the offset to the 269 //local timezone 270 //[Bryan: changing this to omit time zone because erroneous if parser in different zone than sender] 271 if (!offsetExists) { 272 omitOffsetFg = true; 273 // set the offSet field to the current time and local time zone 274 //offSet = DataTypeUtil.getLocalGMTOffset(); 275 } //end if 276 277 //validations are now done store the time value into the private value field 278 value = timeVal; 279 } //end try 280 281 catch (DataTypeException e) { 282 throw e; 283 } //end catch 284 285 catch (Exception e) { 286 throw new DataTypeException(e); 287 } //end catch 288 } //end if 289 else { 290 //set the private value field to null or empty space. 291 value = val; 292 } //end else 293 } //end method 294 295 /** 296 * This method takes in an integer value for the hour and performs validations, 297 * it then sets the value field formatted as an HL7 time 298 * value with hour precision (HH). 299 */ 300 public void setHourPrecision(int hr) throws DataTypeException { 301 try { 302 //validate input value 303 if ((hr < 0) || (hr > 23)) { 304 String msg = "The hour value of the TM datatype must be >=0 and <=23"; 305 throw new DataTypeException(msg); 306 } //end if 307 hour = hr; 308 minute = 0; 309 second = 0; 310 fractionOfSec = 0; 311 offSet = 0; 312 //Here the offset is not defined, we should omit showing it in the 313 //return value from the getValue() method 314 omitOffsetFg = true; 315 value = DataTypeUtil.preAppendZeroes(hr, 2); 316 } //end try 317 318 catch (DataTypeException e) { 319 throw e; 320 } //end catch 321 322 catch (Exception e) { 323 throw new DataTypeException(e.getMessage()); 324 } //end catch 325 326 } //end method 327 328 /** 329 * This method takes in integer values for the hour and minute and performs validations, 330 * it then sets the value field formatted as an HL7 time value 331 * with hour&minute precision (HHMM). 332 */ 333 public void setHourMinutePrecision(int hr, int min) throws DataTypeException { 334 try { 335 this.setHourPrecision(hr); 336 //validate input minute value 337 if ((min < 0) || (min > 59)) { 338 String msg = "The minute value of the TM datatype must be >=0 and <=59"; 339 throw new DataTypeException(msg); 340 } //end if 341 minute = min; 342 second = 0; 343 fractionOfSec = 0; 344 offSet = 0; 345 //Here the offset is not defined, we should omit showing it in the 346 //return value from the getValue() method 347 omitOffsetFg = true; 348 value = value + DataTypeUtil.preAppendZeroes(min, 2); 349 } //end try 350 351 catch (DataTypeException e) { 352 throw e; 353 } //end catch 354 355 catch (Exception e) { 356 throw new DataTypeException(e.getMessage()); 357 } //end catch 358 } //end method 359 360 /** 361 * This method takes in integer values for the hour, minute, seconds, and fractional seconds 362 * (going to the tenthousandths precision). 363 * The method performs validations and then sets the value field formatted as an 364 * HL7 time value with a precision that starts from the hour and goes down to the tenthousandths 365 * of a second (HHMMSS.SSSS). 366 * Note: all of the precisions from tenths down to tenthousandths of a 367 * second are optional. If the precision goes below tenthousandths of a second then the second 368 * value will be rounded to the nearest tenthousandths of a second. 369 */ 370 public void setHourMinSecondPrecision(int hr, int min, float sec) throws DataTypeException { 371 try { 372 this.setHourMinutePrecision(hr, min); 373 //multiply the seconds input value by 10000 and round the result 374 //then divide the number by tenthousand and store it back. 375 //This will round the fractional seconds to the nearest tenthousandths 376 int secMultRound = Math.round(10000F * sec); 377 sec = secMultRound / 10000F; 378 //Now store the second and fractional component 379 second = (int) Math.floor(sec); 380 //validate input seconds value 381 if ((second < 0) || (second >= 60)) { 382 String msg = "The (rounded) second value of the TM datatype must be >=0 and <60"; 383 throw new DataTypeException(msg); 384 } //end if 385 int fractionOfSecInt = secMultRound - (second * 10000); 386 fractionOfSec = fractionOfSecInt / 10000F; 387 String fractString = ""; 388 //Now convert the fractionOfSec field to a string without the leading zero 389 if (fractionOfSec != 0.0F) { 390 fractString = (Float.toString(fractionOfSec)).substring(1); 391 } //end if 392 //Now update the value field 393 offSet = 0; 394 //Here the offset is not defined, we should omit showing it in the 395 //return value from the getValue() method 396 omitOffsetFg = true; 397 value = value + DataTypeUtil.preAppendZeroes(second, 2) + fractString; 398 } //end try 399 400 catch (DataTypeException e) { 401 throw e; 402 } //end catch 403 404 catch (Exception e) { 405 throw new DataTypeException(e); 406 } //end catch 407 } //end method 408 409 /** 410 * This method takes in the four digit (signed) GMT offset and sets the offset 411 * field 412 */ 413 public void setOffset(int signedOffset) throws DataTypeException { 414 try { 415 //When this function is called an offset is being created/updated 416 //we should not omit displaying it in the return value from 417 //the getValue() method 418 omitOffsetFg = false; 419 String offsetStr = Integer.toString(signedOffset); 420 if ((signedOffset >= 0 && offsetStr.length() > 4) || (signedOffset < 0 && offsetStr.length() > 5)) { 421 //The length of the GMT offset must be no greater than 5 characters (including the sign) 422 String msg = 423 "The length of the GMT offset for the TM datatype value does" 424 + " not conform to the allowable format [+/-ZZZZ]. Value: " + signedOffset; 425 throw new DataTypeException(msg); 426 } //end if 427 //obtain the absolute value of the input 428 int absOffset = Math.abs(signedOffset); 429 //extract the hour data from the offset value. 430 //first preappend zeros so we have a 4 char offset value (without sign) 431 offsetStr = DataTypeUtil.preAppendZeroes(absOffset, 4); 432 int hrOffsetInt = Integer.parseInt(offsetStr.substring(0, 2)); 433 //check to see if the hour value is valid 434 if ((hrOffsetInt < 0) || (hrOffsetInt > 23)) { 435 String msg = "The GMT offset hour value of the TM datatype must be >=0 and <=23"; 436 throw new DataTypeException(msg); 437 } //end if 438 //extract the minute data from the offset value. 439 int minOffsetInt = Integer.parseInt(offsetStr.substring(2, 4)); 440 //check to see if the minute value is valid 441 if ((minOffsetInt < 0) || (minOffsetInt > 59)) { 442 String msg = "The GMT offset minute value of the TM datatype must be >=0 and <=59"; 443 throw new DataTypeException(msg); 444 } //end if 445 //The input value is valid, now store it in the offset field 446 offSet = signedOffset; 447 } //end try 448 449 catch (DataTypeException e) { 450 throw e; 451 } //end catch 452 453 catch (Exception e) { 454 throw new DataTypeException(e); 455 } //end catch 456 } //end method 457 458 /** 459 * Returns the HL7 TM string value. 460 */ 461 public String getValue() { 462 //combine the value field with the offSet field and return it 463 String returnVal = null; 464 if (value != null && !value.equals("")) { 465 if (!omitOffsetFg && !value.equals("\"\"")) { 466 int absOffset = Math.abs(offSet); 467 String sign; 468 if (offSet >= 0) { 469 sign = "+"; 470 } //end if 471 else { 472 sign = "-"; 473 } //end else 474 returnVal = value + sign + DataTypeUtil.preAppendZeroes(absOffset, 4); 475 } 476 else { 477 returnVal = value; 478 } //end else 479 } //end if 480 return returnVal; 481 } //end method 482 483 /** 484 * Convenience setter which sets the value using a {@link Calendar} object. Passing in <code>null</code> clears any existing value. 485 * 486 * Note: Sets fields using precision up to the minute 487 * 488 * @param theCalendar The calendar object from which to retrieve values 489 * @since 1.1 490 */ 491 public void setValueToMinute(Calendar theCalendar) throws DataTypeException { 492 if (theCalendar == null) { 493 setValue((String)null); 494 return; 495 } 496 497 int hr = theCalendar.get(Calendar.HOUR_OF_DAY); 498 int min = theCalendar.get(Calendar.MINUTE); 499 setHourMinutePrecision(hr, min); 500 } 501 502 /** 503 * Convenience setter which sets the value using a {@link Date} object. Passing in <code>null</code> clears any existing value. 504 * 505 * Note: Sets fields using precision up to the minute 506 * Note: Date is timezone-agnostic, representing always GMT time 507 * 508 * @param theDate The date object from which to retrieve values 509 * @since 1.1 510 */ 511 public void setValueToMinute(Date theDate) throws DataTypeException { 512 if (theDate == null) { 513 setValue((String)null); 514 return; 515 } 516 517 Calendar calendar = Calendar.getInstance(); 518 calendar.setTime(theDate); 519 setValueToMinute(calendar); 520 } 521 522 /** 523 * Convenience setter which sets the value using a {@link Calendar} object. Passing in <code>null</code> clears any existing value. 524 * 525 * Note: Sets fields using precision up to the second 526 * 527 * @param theCalendar The calendar object from which to retrieve values 528 * @since 1.1 529 */ 530 public void setValueToSecond(Calendar theCalendar) throws DataTypeException { 531 if (theCalendar == null) { 532 setValue((String)null); 533 return; 534 } 535 536 int hr = theCalendar.get(Calendar.HOUR_OF_DAY); 537 int min = theCalendar.get(Calendar.MINUTE); 538 int sec = theCalendar.get(Calendar.SECOND); 539 540 setHourMinSecondPrecision(hr, min, sec); 541 } 542 543 /** 544 * Convenience setter which sets the value using a {@link Calendar} object. Passing in <code>null</code> clears any existing value. 545 * 546 * Note: Sets fields using precision up to the millisecond, including timezone offset 547 * 548 * @param theCalendar The calendar object from which to retrieve values 549 * @since 1.1 550 */ 551 public void setValue(Calendar theCalendar) throws DataTypeException { 552 if (theCalendar == null) { 553 setValue((String)null); 554 return; 555 } 556 557 int hr = theCalendar.get(Calendar.HOUR_OF_DAY); 558 int min = theCalendar.get(Calendar.MINUTE); 559 float sec = theCalendar.get(Calendar.SECOND) + (theCalendar.get(Calendar.MILLISECOND) / 1000.0F); 560 setHourMinSecondPrecision(hr, min, sec); 561 562 // 3410095: care for integer overflow and timezones not at the full hour, e.g. India 563 int hourOffset= theCalendar.get(Calendar.ZONE_OFFSET) / (1000 * 60 * 60); 564 int minuteOffset = (theCalendar.get(Calendar.ZONE_OFFSET) / (1000 * 60)) % 60; 565 int zoneOffset = hourOffset * 100 + minuteOffset; 566 setOffset(zoneOffset); 567 } 568 569 /** 570 * Convenience setter which sets the value using a {@link Calendar} object. Passing in <code>null</code> clears any existing value. 571 * 572 * Note: Sets fields using precision up to the millisecond, and sets the timezone offset to 573 * the current system offset 574 * Note: Date is timezone-agnostic, representing always GMT time 575 * 576 * @param theDate The calendar object from which to retrieve values 577 * @since 1.1 578 */ 579 public void setValue(Date theDate) throws DataTypeException { 580 if (theDate == null) { 581 setValue((String)null); 582 return; 583 } 584 585 GregorianCalendar cal = new GregorianCalendar(); 586 cal.setTime(theDate); 587 setValue(cal); 588 } 589 590 /** 591 * Convenience setter which sets the value using a {@link Date} object. Passing in <code>null</code> clears any existing value. 592 * 593 * Note: Sets fields using precision up to the second 594 * Note: Date is timezone-agnostic, representing always GMT time 595 * 596 * @param theDate The date object from which to retrieve values 597 * @since 1.1 598 */ 599 public void setValueToSecond(Date theDate) throws DataTypeException { 600 if (theDate == null) { 601 setValue((String)null); 602 return; 603 } 604 605 Calendar calendar = Calendar.getInstance(); 606 calendar.setTime(theDate); 607 setValueToSecond(calendar); 608 } 609 610 /** 611 * <p>Return the value as a calendar object.</p> 612 * 613 * <b>Note that only the time component of the return value is set to 614 * the value from this object. Returned value will have today's date</b> 615 * @since 1.1 616 */ 617 public Calendar getValueAsCalendar() { 618 int gmtOff = getGMTOffset(); 619 Calendar retVal; 620 if (gmtOff != GMT_OFFSET_NOT_SET_VALUE && !omitOffsetFg) { 621 int hrOffset = gmtOff / 100; 622 int minOffset = Math.abs(gmtOff % 100); 623 String timeZone = String.format("GMT%+d:%02d", hrOffset, minOffset); 624 retVal = new GregorianCalendar(TimeZone.getTimeZone(timeZone)); 625 } else { 626 retVal = Calendar.getInstance(); 627 } 628 629 retVal.set(Calendar.HOUR_OF_DAY, getHour()); 630 retVal.set(Calendar.MINUTE, getMinute()); 631 retVal.set(Calendar.SECOND, getSecond()); 632 float fractSecond = getFractSecond(); 633 retVal.set(Calendar.MILLISECOND, (int) Math.round(fractSecond * 1000.0)); 634 635 return retVal; 636 } 637 638 639 /** 640 * <p>Return the value as a date object</p> 641 * 642 * <b>Note that only the time component of the return value is set to 643 * the value from this object. Returned value will have today's date</b> 644 * Note: Date is timezone-agnostic, representing always GMT time 645 * @since 1.1 646 */ 647 public Date getValueAsDate() { 648 return getValueAsCalendar().getTime(); 649 } 650 651 /** 652 * Returns the hour as an integer. 653 */ 654 public int getHour() { 655 return hour; 656 } //end method 657 658 /** 659 * Returns the minute as an integer. 660 */ 661 public int getMinute() { 662 return minute; 663 } //end method 664 665 /** 666 * Returns the second as an integer. 667 */ 668 public int getSecond() { 669 return second; 670 } //end method 671 672 /** 673 * Returns the fractional second value as a float. 674 */ 675 public float getFractSecond() { 676 return fractionOfSec; 677 } //end method 678 679 /** 680 * Returns the GMT offset value as an integer, {@link #GMT_OFFSET_NOT_SET_VALUE} if not set. 681 */ 682 public int getGMTOffset() { 683 return offSet; 684 } //end method 685 686 /** 687 * Returns a string value representing the input Gregorian Calendar object in 688 * an Hl7 Time Format. 689 */ 690 public static String toHl7TMFormat(GregorianCalendar cal) throws DataTypeException { 691 String val; 692 try { 693 //set the input cal object so that it can report errors 694 //on it's value 695 cal.setLenient(false); 696 int calHour = cal.get(GregorianCalendar.HOUR_OF_DAY); 697 int calMin = cal.get(GregorianCalendar.MINUTE); 698 int calSec = cal.get(GregorianCalendar.SECOND); 699 int calMilli = cal.get(GregorianCalendar.MILLISECOND); 700 //the inputs seconds and milli seconds should be combined into a float type 701 float fractSec = calMilli / 1000F; 702 float calSecFloat = calSec + fractSec; 703 int calOffset = cal.get(GregorianCalendar.ZONE_OFFSET) + cal.get(GregorianCalendar.DST_OFFSET); 704 //Note the input's Offset value is in milliseconds, we must convert it to 705 //a 4 digit integer in the HL7 Offset format. 706 int offSetSignInt; 707 if (calOffset < 0) { 708 offSetSignInt = -1; 709 } 710 else { 711 offSetSignInt = 1; 712 } 713 //get the absolute value of the gmtOffSet 714 int absGmtOffSet = Math.abs(calOffset); 715 int gmtOffSetHours = absGmtOffSet / (3600 * 1000); 716 int gmtOffSetMin = (absGmtOffSet / 60000) % (60); 717 //reset calOffset 718 calOffset = ((gmtOffSetHours * 100) + gmtOffSetMin) * offSetSignInt; 719 //Create an object of the TS class and populate it with the above values 720 //then return the HL7 string value from the object 721 CommonTM tm = new CommonTM(); 722 tm.setHourMinSecondPrecision(calHour, calMin, calSecFloat); 723 tm.setOffset(calOffset); 724 val = tm.getValue(); 725 } // end try 726 727 catch (DataTypeException e) { 728 throw e; 729 } //end catch 730 731 catch (Exception e) { 732 throw new DataTypeException(e); 733 } //end catch 734 return val; 735 } //end method 736 737} //end class