1
2
3
4
5
6 package dev.metaschema.core.metapath.item.atomic;
7
8 import java.time.LocalTime;
9 import java.time.OffsetTime;
10 import java.time.ZoneOffset;
11
12 import dev.metaschema.core.datatype.adapter.MetaschemaDataTypeProvider;
13 import dev.metaschema.core.datatype.object.AmbiguousTime;
14 import dev.metaschema.core.metapath.MetapathConstants;
15 import dev.metaschema.core.metapath.function.DateTimeFunctionException;
16 import dev.metaschema.core.metapath.function.InvalidValueForCastFunctionException;
17 import dev.metaschema.core.metapath.item.atomic.impl.TimeWithoutTimeZoneItemImpl;
18 import dev.metaschema.core.metapath.type.IAtomicOrUnionType;
19 import dev.metaschema.core.metapath.type.InvalidTypeMetapathException;
20 import dev.metaschema.core.util.ObjectUtils;
21 import edu.umd.cs.findbugs.annotations.NonNull;
22 import edu.umd.cs.findbugs.annotations.Nullable;
23
24
25
26
27
28
29
30
31
32 public interface ITimeItem extends ITemporalItem {
33
34
35
36
37
38 @NonNull
39 static IAtomicOrUnionType<ITimeItem> type() {
40 return MetaschemaDataTypeProvider.TIME.getItemType();
41 }
42
43 @Override
44 default IAtomicOrUnionType<? extends ITimeItem> getType() {
45 return type();
46 }
47
48
49
50
51
52
53
54
55 @NonNull
56 static ITimeItem valueOf(@NonNull String value) {
57 try {
58 return valueOf(MetaschemaDataTypeProvider.TIME.parse(value));
59 } catch (IllegalArgumentException ex) {
60 throw new InvalidTypeMetapathException(
61 null,
62 String.format("Invalid date/time value '%s'. %s",
63 value,
64 ex.getLocalizedMessage()),
65 ex);
66 }
67 }
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84 @NonNull
85 static ITimeItem valueOf(@NonNull OffsetTime value, boolean hasTimeZone) {
86 return hasTimeZone
87 ? ITimeWithTimeZoneItem.valueOf(value)
88 : valueOf(new AmbiguousTime(value, false));
89 }
90
91
92
93
94
95
96
97
98
99
100
101
102
103 @NonNull
104 static ITimeItem valueOf(@NonNull AmbiguousTime value) {
105 return value.hasTimeZone()
106 ? ITimeWithTimeZoneItem.valueOf(value.getValue())
107 : new TimeWithoutTimeZoneItemImpl(value);
108 }
109
110 @Override
111 default boolean hasDate() {
112 return false;
113 }
114
115 @Override
116 default boolean hasTime() {
117 return true;
118 }
119
120 @Override
121 boolean hasTimezone();
122
123 @Override
124 default int getYear() {
125 return 0;
126 }
127
128 @Override
129 default int getMonth() {
130 return 0;
131 }
132
133 @Override
134 default int getDay() {
135 return 0;
136 }
137
138 @Override
139 default int getHour() {
140 return asOffsetTime().getHour();
141 }
142
143 @Override
144 default int getMinute() {
145 return asOffsetTime().getMinute();
146 }
147
148 @Override
149 default int getSecond() {
150 return asOffsetTime().getSecond();
151 }
152
153 @Override
154 default int getNano() {
155 return asOffsetTime().getNano();
156 }
157
158 @Override
159 @Nullable
160 default ZoneOffset getZoneOffset() {
161 return hasTimezone() ? asOffsetTime().getOffset() : null;
162 }
163
164
165
166
167
168
169 @NonNull
170 OffsetTime asOffsetTime();
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201 @Override
202 default ITimeItem replaceTimezone(@Nullable IDayTimeDurationItem offset) {
203 return offset == null
204 ? hasTimezone()
205 ? valueOf(ObjectUtils.notNull(asOffsetTime().withOffsetSameLocal(ZoneOffset.UTC)), false)
206 : this
207 : hasTimezone()
208 ? valueOf(IDateTimeItem.valueOf(MetapathConstants.REFERENCE_DATE_ITEM, this)
209 .replaceTimezone(offset).asOffsetTime(),
210 true)
211 : valueOf(
212 ObjectUtils.notNull(asOffsetTime().withOffsetSameLocal(offset.asZoneOffset())),
213 true);
214 }
215
216
217
218
219
220
221
222
223
224
225
226 @NonNull
227 static ITimeItem cast(@NonNull IAnyAtomicItem item) {
228 ITimeItem retval;
229 if (item instanceof ITimeItem) {
230 retval = (ITimeItem) item;
231 } else if (item instanceof IStringItem || item instanceof IUntypedAtomicItem) {
232 try {
233 retval = valueOf(item.asString());
234 } catch (IllegalStateException | InvalidTypeMetapathException ex) {
235
236 throw new InvalidValueForCastFunctionException(ex);
237 }
238 } else {
239 throw new InvalidValueForCastFunctionException(
240 String.format("unsupported item type '%s'", item.getClass().getName()));
241 }
242 return retval;
243 }
244
245 @Override
246 default ITimeItem castAsType(IAnyAtomicItem item) {
247 return cast(item);
248 }
249
250
251
252
253
254
255 @NonNull
256 default LocalTime asLocalTime() {
257 return ObjectUtils.notNull(asOffsetTime().toLocalTime());
258 }
259 }