1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 package org.openehealth.ipf.commons.ihe.xds.core.metadata;
17
18 import ca.uhn.hl7v2.model.DataTypeException;
19 import ca.uhn.hl7v2.model.primitive.CommonTS;
20 import lombok.Getter;
21 import lombok.Setter;
22 import org.apache.commons.lang3.StringUtils;
23 import org.joda.time.DateTime;
24 import org.joda.time.DateTimeZone;
25 import org.joda.time.format.DateTimeFormat;
26 import org.joda.time.format.DateTimeFormatter;
27 import org.openehealth.ipf.commons.ihe.xds.core.metadata.jaxbadapters.DateTimeAdapter;
28 import org.openehealth.ipf.commons.ihe.xds.core.validate.ValidationMessage;
29 import org.openehealth.ipf.commons.ihe.xds.core.validate.XDSMetaDataException;
30
31 import javax.xml.bind.annotation.*;
32 import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter;
33 import java.io.Serializable;
34 import java.util.EnumMap;
35 import java.util.Map;
36 import java.util.Objects;
37
38
39
40
41
42
43 @XmlAccessorType(XmlAccessType.FIELD)
44 @XmlType(name = "Timestamp", propOrder = {"dateTime", "precision"})
45 public class Timestamp implements Serializable {
46 private static final long serialVersionUID = 4324651691599629794L;
47
48 @XmlEnum
49 @XmlType(name = "Precision", namespace = "http://www.openehealth.org/ipf/xds")
50 public enum Precision {
51 YEAR, MONTH, DAY, HOUR, MINUTE, SECOND
52 }
53
54 private static final Map<Precision, DateTimeFormatter> FORMATTERS = new EnumMap<>(Precision.class);
55 static {
56 FORMATTERS.put(Precision.YEAR, DateTimeFormat.forPattern("yyyy"));
57 FORMATTERS.put(Precision.MONTH, DateTimeFormat.forPattern("yyyyMM"));
58 FORMATTERS.put(Precision.DAY, DateTimeFormat.forPattern("yyyyMMdd"));
59 FORMATTERS.put(Precision.HOUR, DateTimeFormat.forPattern("yyyyMMddHH"));
60 FORMATTERS.put(Precision.MINUTE, DateTimeFormat.forPattern("yyyyMMddHHmm"));
61 FORMATTERS.put(Precision.SECOND, DateTimeFormat.forPattern("yyyyMMddHHmmss"));
62 }
63
64
65
66
67 @XmlAttribute
68 @XmlJavaTypeAdapter(value = DateTimeAdapter.class)
69 @Getter private DateTime dateTime;
70
71
72
73
74 @XmlAttribute
75 @Setter private Precision precision;
76
77 public Timestamp() {
78
79 }
80
81
82
83
84 public Timestamp(DateTime dateTime, Precision precision) {
85 setDateTime(dateTime);
86 setPrecision(precision);
87 }
88
89
90
91
92
93
94
95
96
97 public static Timestamp fromHL7(String s) {
98 if (StringUtils.isEmpty(s)) {
99 return null;
100 }
101
102 int pos = Math.max(s.indexOf('-'), s.indexOf('+'));
103 int len = (pos >= 0) ? pos : s.length();
104
105
106 Precision precision;
107 if (len >= 14) {
108 precision = Precision.SECOND;
109 } else if (len >= 12) {
110 precision = Precision.MINUTE;
111 } else if (len >= 10) {
112 precision = Precision.HOUR;
113 } else if (len >= 8) {
114 precision = Precision.DAY;
115 } else if (len >= 6) {
116 precision = Precision.MONTH;
117 } else {
118 precision = Precision.YEAR;
119 }
120
121
122 if (pos < 0) {
123 s += "+0000";
124 }
125
126
127 try {
128 CommonTS ts = new CommonTS(s);
129 DateTime dateTime = new DateTime(
130 ts.getYear(),
131 (ts.getMonth() == 0) ? 1 : ts.getMonth(),
132 (ts.getDay() == 0) ? 1 : ts.getDay(),
133 ts.getHour(),
134 ts.getMinute(),
135 ts.getSecond(),
136 DateTimeZone.forOffsetHoursMinutes(
137 ts.getGMTOffset() / 100,
138 ts.getGMTOffset() % 100));
139 return new Timestamp(dateTime.toDateTime(DateTimeZone.UTC), precision);
140 } catch (DataTypeException e) {
141 throw new XDSMetaDataException(ValidationMessage.INVALID_TIME, s);
142 }
143 }
144
145
146
147
148
149
150
151
152 public static String toHL7(Timestamp timestamp) {
153 return (timestamp != null) ? timestamp.toHL7() : null;
154 }
155
156 private String toHL7() {
157 return FORMATTERS.get(getPrecision()).print(getDateTime().toDateTime(DateTimeZone.UTC));
158 }
159
160 public void setDateTime(DateTime dateTime) {
161 this.dateTime = (dateTime != null) ? dateTime.toDateTime(DateTimeZone.UTC) : null;
162 }
163
164 public Precision getPrecision() {
165 return (precision != null) ? precision : Precision.SECOND;
166 }
167
168
169
170
171
172
173 @Override
174 public boolean equals(Object o) {
175 if (this == o) return true;
176 if (o == null || getClass() != o.getClass()) return false;
177
178 Timestamp timestamp = (Timestamp) o;
179 return StringUtils.equals(toHL7(this), toHL7(timestamp));
180 }
181
182 @Override
183 public int hashCode() {
184 return Objects.hash(dateTime, precision);
185 }
186
187 @Override
188 public String toString() {
189 return "Timestamp(" +
190 "dateTime=" + dateTime +
191 ", precision=" + precision +
192 ')';
193 }
194 }