| Classes in this File | Line Coverage | Branch Coverage | Complexity | ||||
| CommonTS |
|
| 4.6923076923076925;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 |