1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28 package ca.uhn.hl7v2.model.primitive;
29
30 import java.util.Calendar;
31 import java.util.Date;
32 import java.util.GregorianCalendar;
33 import java.util.TimeZone;
34 import java.io.Serializable;
35
36 import ca.uhn.hl7v2.model.DataTypeException;
37 import ca.uhn.hl7v2.model.DataTypeUtil;
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76 @SuppressWarnings("serial")
77 public class CommonTM implements Serializable {
78
79
80
81
82 public static final int GMT_OFFSET_NOT_SET_VALUE = -99;
83
84 private String value;
85 private int hour;
86 private int minute;
87 private int second;
88 private float fractionOfSec;
89 private int offSet;
90 private boolean omitOffsetFg = false;
91
92
93
94
95
96 public CommonTM() {
97
98 value = null;
99 hour = 0;
100 minute = 0;
101 second = 0;
102 fractionOfSec = 0;
103 offSet = GMT_OFFSET_NOT_SET_VALUE;
104 }
105
106
107
108
109
110
111 public CommonTM(String val) throws DataTypeException {
112 this.setValue(val);
113 }
114
115
116
117
118
119
120
121
122
123
124
125 public void setValue(String val) throws DataTypeException {
126
127 if (val != null && !val.equals("") && !val.equals("\"\"")) {
128
129
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
145
146
147
148 String timeVal = val;
149 String tempOffset = null;
150 if (offsetExists) {
151 timeVal = val.substring(0, indexOfSign);
152 tempOffset = val.substring(indexOfSign);
153 }
154
155 if (offsetExists && (tempOffset.length() != 5)) {
156
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 }
162
163 if (d != -1) {
164
165
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 }
172 }
173
174 if (d == -1) {
175
176
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 }
183 }
184
185
186 if (timeVal.length() >= 2) {
187
188
189 int hrInt = Integer.parseInt(timeVal.substring(0, 2));
190
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 }
195 hour = hrInt;
196 }
197
198 if (timeVal.length() >= 4) {
199
200
201
202 int minInt = Integer.parseInt(timeVal.substring(2, 4));
203
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 }
208 minute = minInt;
209 }
210
211 if (timeVal.length() >= 6) {
212
213
214
215 int secInt = Integer.parseInt(timeVal.substring(4, 6));
216
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 }
221 second = secInt;
222 }
223
224 if (timeVal.length() >= 8) {
225
226
227
228 float fract = Float.parseFloat(timeVal.substring(6));
229
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 }
234 fractionOfSec = fract;
235 }
236
237
238 if (offsetExists) {
239
240
241 omitOffsetFg = false;
242
243 String tempOffsetNoS = tempOffset.substring(1);
244
245
246 int offsetInt = Integer.parseInt(tempOffsetNoS.substring(0, 2));
247
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 }
252
253
254 offsetInt = Integer.parseInt(tempOffsetNoS.substring(2, 4));
255
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 }
260
261 offSet = Integer.parseInt(tempOffsetNoS);
262
263 if (sm != -1) {
264 offSet = -1 * offSet;
265 }
266 }
267
268
269
270
271 if (!offsetExists) {
272 omitOffsetFg = true;
273
274
275 }
276
277
278 value = timeVal;
279 }
280
281 catch (DataTypeException e) {
282 throw e;
283 }
284
285 catch (Exception e) {
286 throw new DataTypeException(e);
287 }
288 }
289 else {
290
291 value = val;
292 }
293 }
294
295
296
297
298
299
300 public void setHourPrecision(int hr) throws DataTypeException {
301 try {
302
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 }
307 hour = hr;
308 minute = 0;
309 second = 0;
310 fractionOfSec = 0;
311 offSet = 0;
312
313
314 omitOffsetFg = true;
315 value = DataTypeUtil.preAppendZeroes(hr, 2);
316 }
317
318 catch (DataTypeException e) {
319 throw e;
320 }
321
322 catch (Exception e) {
323 throw new DataTypeException(e.getMessage());
324 }
325
326 }
327
328
329
330
331
332
333 public void setHourMinutePrecision(int hr, int min) throws DataTypeException {
334 try {
335 this.setHourPrecision(hr);
336
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 }
341 minute = min;
342 second = 0;
343 fractionOfSec = 0;
344 offSet = 0;
345
346
347 omitOffsetFg = true;
348 value = value + DataTypeUtil.preAppendZeroes(min, 2);
349 }
350
351 catch (DataTypeException e) {
352 throw e;
353 }
354
355 catch (Exception e) {
356 throw new DataTypeException(e.getMessage());
357 }
358 }
359
360
361
362
363
364
365
366
367
368
369
370 public void setHourMinSecondPrecision(int hr, int min, float sec) throws DataTypeException {
371 try {
372 this.setHourMinutePrecision(hr, min);
373
374
375
376 int secMultRound = Math.round(10000F * sec);
377 sec = secMultRound / 10000F;
378
379 second = (int) Math.floor(sec);
380
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 }
385 int fractionOfSecInt = secMultRound - (second * 10000);
386 fractionOfSec = fractionOfSecInt / 10000F;
387 String fractString = "";
388
389 if (fractionOfSec != 0.0F) {
390 fractString = (Float.toString(fractionOfSec)).substring(1);
391 }
392
393 offSet = 0;
394
395
396 omitOffsetFg = true;
397 value = value + DataTypeUtil.preAppendZeroes(second, 2) + fractString;
398 }
399
400 catch (DataTypeException e) {
401 throw e;
402 }
403
404 catch (Exception e) {
405 throw new DataTypeException(e);
406 }
407 }
408
409
410
411
412
413 public void setOffset(int signedOffset) throws DataTypeException {
414 try {
415
416
417
418 omitOffsetFg = false;
419 String offsetStr = Integer.toString(signedOffset);
420 if ((signedOffset >= 0 && offsetStr.length() > 4) || (signedOffset < 0 && offsetStr.length() > 5)) {
421
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 }
427
428 int absOffset = Math.abs(signedOffset);
429
430
431 offsetStr = DataTypeUtil.preAppendZeroes(absOffset, 4);
432 int hrOffsetInt = Integer.parseInt(offsetStr.substring(0, 2));
433
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 }
438
439 int minOffsetInt = Integer.parseInt(offsetStr.substring(2, 4));
440
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 }
445
446 offSet = signedOffset;
447 }
448
449 catch (DataTypeException e) {
450 throw e;
451 }
452
453 catch (Exception e) {
454 throw new DataTypeException(e);
455 }
456 }
457
458
459
460
461 public String getValue() {
462
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 }
471 else {
472 sign = "-";
473 }
474 returnVal = value + sign + DataTypeUtil.preAppendZeroes(absOffset, 4);
475 }
476 else {
477 returnVal = value;
478 }
479 }
480 return returnVal;
481 }
482
483
484
485
486
487
488
489
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
504
505
506
507
508
509
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
524
525
526
527
528
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
545
546
547
548
549
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
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
571
572
573
574
575
576
577
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
592
593
594
595
596
597
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
612
613
614
615
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
641
642
643
644
645
646
647 public Date getValueAsDate() {
648 return getValueAsCalendar().getTime();
649 }
650
651
652
653
654 public int getHour() {
655 return hour;
656 }
657
658
659
660
661 public int getMinute() {
662 return minute;
663 }
664
665
666
667
668 public int getSecond() {
669 return second;
670 }
671
672
673
674
675 public float getFractSecond() {
676 return fractionOfSec;
677 }
678
679
680
681
682 public int getGMTOffset() {
683 return offSet;
684 }
685
686
687
688
689
690 public static String toHl7TMFormat(GregorianCalendar cal) throws DataTypeException {
691 String val;
692 try {
693
694
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
701 float fractSec = calMilli / 1000F;
702 float calSecFloat = calSec + fractSec;
703 int calOffset = cal.get(GregorianCalendar.ZONE_OFFSET) + cal.get(GregorianCalendar.DST_OFFSET);
704
705
706 int offSetSignInt;
707 if (calOffset < 0) {
708 offSetSignInt = -1;
709 }
710 else {
711 offSetSignInt = 1;
712 }
713
714 int absGmtOffSet = Math.abs(calOffset);
715 int gmtOffSetHours = absGmtOffSet / (3600 * 1000);
716 int gmtOffSetMin = (absGmtOffSet / 60000) % (60);
717
718 calOffset = ((gmtOffSetHours * 100) + gmtOffSetMin) * offSetSignInt;
719
720
721 CommonTMitive/CommonTM.html#CommonTM">CommonTM tm = new CommonTM();
722 tm.setHourMinSecondPrecision(calHour, calMin, calSecFloat);
723 tm.setOffset(calOffset);
724 val = tm.getValue();
725 }
726
727 catch (DataTypeException e) {
728 throw e;
729 }
730
731 catch (Exception e) {
732 throw new DataTypeException(e);
733 }
734 return val;
735 }
736
737 }