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 |