1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package org.orekit.time;
18
19 import java.io.Serializable;
20 import java.text.DecimalFormat;
21 import java.text.DecimalFormatSymbols;
22 import java.util.Locale;
23
24 import org.hipparchus.util.FastMath;
25 import org.orekit.utils.Constants;
26
27
28
29
30
31
32
33
34
35 public class DateTimeComponents implements Serializable, Comparable<DateTimeComponents> {
36
37
38
39
40
41
42 public static final DateTimeComponents JULIAN_EPOCH =
43 new DateTimeComponents(DateComponents.JULIAN_EPOCH, TimeComponents.H12);
44
45
46 private static final long serialVersionUID = 5061129505488924484L;
47
48
49 private final DateComponents date;
50
51
52 private final TimeComponents time;
53
54
55
56
57
58 public DateTimeComponents(final DateComponents date, final TimeComponents time) {
59 this.date = date;
60 this.time = time;
61 }
62
63
64
65
66
67
68
69
70
71
72
73
74 public DateTimeComponents(final int year, final int month, final int day,
75 final int hour, final int minute, final double second)
76 throws IllegalArgumentException {
77 this.date = new DateComponents(year, month, day);
78 this.time = new TimeComponents(hour, minute, second);
79 }
80
81
82
83
84
85
86
87
88
89
90
91
92 public DateTimeComponents(final int year, final Month month, final int day,
93 final int hour, final int minute, final double second)
94 throws IllegalArgumentException {
95 this.date = new DateComponents(year, month, day);
96 this.time = new TimeComponents(hour, minute, second);
97 }
98
99
100
101
102
103
104
105
106
107
108 public DateTimeComponents(final int year, final int month, final int day)
109 throws IllegalArgumentException {
110 this.date = new DateComponents(year, month, day);
111 this.time = TimeComponents.H00;
112 }
113
114
115
116
117
118
119
120
121
122
123 public DateTimeComponents(final int year, final Month month, final int day)
124 throws IllegalArgumentException {
125 this.date = new DateComponents(year, month, day);
126 this.time = TimeComponents.H00;
127 }
128
129
130
131
132
133
134 public DateTimeComponents(final DateTimeComponents reference,
135 final double offset) {
136
137
138 int day = reference.getDate().getJ2000Day();
139 double seconds = reference.getTime().getSecondsInLocalDay();
140
141
142 seconds += offset;
143
144
145 final int dayShift = (int) FastMath.floor(seconds / Constants.JULIAN_DAY);
146 seconds -= Constants.JULIAN_DAY * dayShift;
147 day += dayShift;
148 final TimeComponents tmpTime = new TimeComponents(seconds);
149
150
151 this.date = new DateComponents(day);
152 this.time = new TimeComponents(tmpTime.getHour(), tmpTime.getMinute(), tmpTime.getSecond(),
153 reference.getTime().getMinutesFromUTC());
154
155 }
156
157
158
159
160
161
162
163
164
165
166
167 public static DateTimeComponents parseDateTime(final String string) {
168
169
170 final int tIndex = string.indexOf('T');
171 if (tIndex > 0) {
172 return new DateTimeComponents(DateComponents.parseDate(string.substring(0, tIndex)),
173 TimeComponents.parseTime(string.substring(tIndex + 1)));
174 }
175
176 return new DateTimeComponents(DateComponents.parseDate(string), TimeComponents.H00);
177
178 }
179
180
181
182
183
184
185
186 public double offsetFrom(final DateTimeComponents dateTime) {
187 final int dateOffset = date.getJ2000Day() - dateTime.date.getJ2000Day();
188 final double timeOffset = time.getSecondsInUTCDay() - dateTime.time.getSecondsInUTCDay();
189 return Constants.JULIAN_DAY * dateOffset + timeOffset;
190 }
191
192
193
194
195 public DateComponents getDate() {
196 return date;
197 }
198
199
200
201
202 public TimeComponents getTime() {
203 return time;
204 }
205
206
207 public int compareTo(final DateTimeComponents other) {
208 final int dateComparison = date.compareTo(other.date);
209 if (dateComparison < 0) {
210 return -1;
211 } else if (dateComparison > 0) {
212 return 1;
213 }
214 return time.compareTo(other.time);
215 }
216
217
218 public boolean equals(final Object other) {
219 try {
220 final DateTimeComponents otherDateTime = (DateTimeComponents) other;
221 return otherDateTime != null &&
222 date.equals(otherDateTime.date) && time.equals(otherDateTime.time);
223 } catch (ClassCastException cce) {
224 return false;
225 }
226 }
227
228
229 public int hashCode() {
230 return (date.hashCode() << 16) ^ time.hashCode();
231 }
232
233
234
235
236
237 public String toString() {
238 return date.toString() + 'T' + time.toString();
239 }
240
241
242
243
244
245
246
247
248
249 public String toStringWithoutUtcOffset() {
250 return date.toString() + 'T' + time.toStringWithoutUtcOffset();
251 }
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266 public String toString(final int minuteDuration) {
267 return toString(minuteDuration, 3);
268 }
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287 public String toString(final int minuteDuration, final int fractionDigits) {
288 final DecimalFormat secondsFormat =
289 new DecimalFormat("00", new DecimalFormatSymbols(Locale.US));
290 secondsFormat.setMaximumFractionDigits(fractionDigits);
291 secondsFormat.setMinimumFractionDigits(fractionDigits);
292 DateComponents roundedDate = this.date;
293 TimeComponents roundedTime = this.time;
294 double second = time.getSecond();
295 final double wrap = minuteDuration - 0.5 * FastMath.pow(10, -fractionDigits);
296 if (second >= wrap) {
297
298 int minute = time.getMinute();
299 int hour = time.getHour();
300 int j2000 = date.getJ2000Day();
301 second = 0;
302 ++minute;
303 if (minute > 59) {
304 minute = 0;
305 ++hour;
306 if (hour > 23) {
307 hour = 0;
308 ++j2000;
309 }
310 }
311 roundedDate = new DateComponents(j2000);
312 roundedTime = new TimeComponents(hour, minute, second);
313 }
314 return roundedDate.toString() + 'T' +
315 roundedTime.toStringWithoutUtcOffset(secondsFormat) +
316 roundedTime.formatUtcOffset();
317 }
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335 public String toStringRfc3339() {
336 final DateComponents d = this.getDate();
337 final TimeComponents t = this.getTime();
338
339 final String dateString = String.format("%04d-%02d-%02dT",
340 d.getYear(), d.getMonth(), d.getDay());
341
342 final String timeString;
343 if (t.getSecondsInLocalDay() != 0) {
344 final DecimalFormat format = new DecimalFormat("00.##############", new DecimalFormatSymbols(Locale.US));
345 timeString = String.format("%02d:%02d:", t.getHour(), t.getMinute()) +
346 format.format(t.getSecond());
347 } else {
348
349 timeString = "00:00:00";
350 }
351
352 final int minutesFromUTC = t.getMinutesFromUTC();
353 final String timeZoneString;
354 if (minutesFromUTC == 0) {
355 timeZoneString = "Z";
356 } else {
357
358 final String sign = minutesFromUTC < 0 ? "-" : "+";
359 final int utcOffset = FastMath.abs(minutesFromUTC);
360 final int hourOffset = utcOffset / 60;
361 final int minuteOffset = utcOffset % 60;
362 timeZoneString = sign + String.format("%02d:%02d", hourOffset, minuteOffset);
363 }
364 return dateString + timeString + timeZoneString;
365 }
366
367 }
368