• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

trydofor / professional-mirana / #68

31 Aug 2024 02:56AM UTC coverage: 84.4% (+1.0%) from 83.382%
#68

push

web-flow
Merge pull request #45 from trydofor/develop

v2.7.3 with minor change

474 of 568 new or added lines in 27 files covered. (83.45%)

8 existing lines in 6 files now uncovered.

5237 of 6205 relevant lines covered (84.4%)

0.84 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

98.22
/src/main/java/pro/fessional/mirana/time/DateFormatter.java
1
package pro.fessional.mirana.time;
2

3
import org.jetbrains.annotations.NotNull;
4
import org.jetbrains.annotations.Nullable;
5
import pro.fessional.mirana.data.Null;
6
import pro.fessional.mirana.text.HalfCharUtil;
7

8
import java.text.DateFormat;
9
import java.text.SimpleDateFormat;
10
import java.time.LocalDate;
11
import java.time.LocalDateTime;
12
import java.time.LocalTime;
13
import java.time.OffsetDateTime;
14
import java.time.ZoneId;
15
import java.time.ZonedDateTime;
16
import java.time.format.DateTimeFormatter;
17
import java.util.Date;
18

19
/**
20
 * <pre>
21
 * Thread-safe. Faster than normal formatter.
22
 *
23
 * - DateTimeFormatter is immutable and thread-safe.
24
 * - DateFormat is not thread-safe.
25
 *
26
 * see <a href="https://javarevisited.blogspot.com/2013/01/threadlocal-memory-leak-in-java-web.html">threadlocal-memory-leak-in-java-web</a>
27
 * see <a href="https://stackoverflow.com/questions/17968803/threadlocal-memory-leak">threadlocal-memory-leak</a>
28
 *
29
 * </pre>
30
 *
31
 * @author trydofor
32
 * @since 2019-07-03
33
 */
34

UNCOV
35
public class DateFormatter {
×
36

37
    public static final String PTN_DATE_10 = "yyyy-MM-dd";
38
    public static final String PTN_TIME_08 = "HH:mm:ss";
39
    public static final String PTN_TIME_12 = "HH:mm:ss.SSS";
40
    public static final String PTN_FULL_19 = "yyyy-MM-dd HH:mm:ss";
41
    public static final String PTN_FULL_23 = "yyyy-MM-dd HH:mm:ss.SSS";
42

43
    public static final String PTN_FULL_TZ = "yyyy[-MM][-dd][ ][HH][:mm][:ss][ ][VV]";
44
    public static final String PTN_FULL_OZ = "yyyy[-MM][-dd][ ][HH][:mm][:ss][ ][xxx]";
45

46
    public static final String PTN_TIME_PSE = "H[:m][:s][.SSS]";
47
    public static final String PTN_DATE_PSE = "[yyyy][yy][-][/][.][M][-][/][.][d]";
48
    public static final String PTN_FULL_PSE = "[yyyy][yy][-][/][.][M][-][/][.][d][ ]['T'][H][:m][:s][.SSS]";
49
    public static final String PTN_ZONE_PSE = "[yyyy][yy][-][/][.][M][-][/][.][d][ ]['T'][H][:m][:s][.SSS][ ][XXXXX][XXXX][XXX][XX][X][ ]['['][VV][']']";
50
    public static final String PTN_DATE_PSE_US = "[MMMM][MMM][M][-][/][.][d][-][/][.][yyyy][yy]";
51
    public static final String PTN_FULL_PSE_US = "[MMMM][MMM][M][-][/][.][d][-][/][.][yyyy][yy][ ]['T'][H][:m][:s][.SSS]";
52
    public static final String PTN_ZONE_PSE_US = "[MMMM][MMM][M][-][/][.][d][-][/][.][yyyy][yy][ ]['T'][H][:m][:s][.SSS][ ][XXXXX][XXXX][XXX][XX][X][ ]['['][VV][']']";
53

54
    // This class is immutable and thread-safe.
55
    public static final DateTimeFormatter FMT_DATE_10 = DateTimeFormatter.ofPattern(PTN_DATE_10);
1✔
56
    public static final DateTimeFormatter FMT_TIME_08 = DateTimeFormatter.ofPattern(PTN_TIME_08);
1✔
57
    public static final DateTimeFormatter FMT_TIME_12 = DateTimeFormatter.ofPattern(PTN_TIME_12);
1✔
58
    public static final DateTimeFormatter FMT_FULL_19 = DateTimeFormatter.ofPattern(PTN_FULL_19);
1✔
59
    public static final DateTimeFormatter FMT_FULL_23 = DateTimeFormatter.ofPattern(PTN_FULL_23);
1✔
60

61
    public static final DateTimeFormatter FMT_TIME_PSE = DateTimeFormatter.ofPattern(PTN_TIME_PSE);
1✔
62
    public static final DateTimeFormatter FMT_DATE_PSE = DateTimeFormatter.ofPattern(PTN_DATE_PSE);
1✔
63
    public static final DateTimeFormatter FMT_FULL_PSE = DateTimeFormatter.ofPattern(PTN_FULL_PSE);
1✔
64
    public static final DateTimeFormatter FMT_ZONE_PSE = DateTimeFormatter.ofPattern(PTN_ZONE_PSE);
1✔
65
    public static final DateTimeFormatter FMT_DATE_PSE_US = DateTimeFormatter.ofPattern(PTN_DATE_PSE_US);
1✔
66
    public static final DateTimeFormatter FMT_FULL_PSE_US = DateTimeFormatter.ofPattern(PTN_FULL_PSE_US);
1✔
67
    public static final DateTimeFormatter FMT_ZONE_PSE_US = DateTimeFormatter.ofPattern(PTN_ZONE_PSE_US);
1✔
68

69
    public static final DateTimeFormatter FMT_FULL_TZ = DateTimeFormatter.ofPattern(PTN_FULL_TZ);
1✔
70
    public static final DateTimeFormatter FMT_FULL_OZ = DateTimeFormatter.ofPattern(PTN_FULL_OZ);
1✔
71

72

73
    /** no leak, for static */
74
    public static final ThreadLocal<DateFormat> DATE_FORMAT_19 = ThreadLocal.withInitial(() -> new SimpleDateFormat(PTN_FULL_19));
1✔
75
    /** no leak, for static */
76
    public static final ThreadLocal<DateFormat> DATE_FORMAT_23 = ThreadLocal.withInitial(() -> new SimpleDateFormat(PTN_FULL_23));
1✔
77

78

79
    public static DateFormat full19() {
80
        return DATE_FORMAT_19.get();
1✔
81
    }
82

83
    public static DateFormat full23() {
84
        return DATE_FORMAT_23.get();
1✔
85
    }
86

87

88
    @NotNull
89
    public static String fullTz(@Nullable ZonedDateTime date) {
90
        if (date == null) return Null.Str;
1✔
91
        return FMT_FULL_TZ.format(date);
1✔
92
    }
93

94

95
    @NotNull
96
    public static String fullTz(@Nullable OffsetDateTime date) {
97
        if (date == null) return Null.Str;
1✔
98
        return FMT_FULL_OZ.format(date);
1✔
99
    }
100

101
    /**
102
     * Format to yyyy-MM-dd. empty string if null.
103
     */
104
    @NotNull
105
    public static String date10(@Nullable ZonedDateTime date) {
106
        return date10(date, null);
1✔
107
    }
108

109
    /**
110
     * Format to yyyy-MM-dd HH:mm:ss or yyyy-MM-dd HH:mm:ss.SSS. empty string if null.
111
     */
112
    @NotNull
113
    public static String full(@Nullable ZonedDateTime date) {
114
        return full(date, null);
1✔
115
    }
116

117
    /**
118
     * Format to yyyy-MM-dd HH:mm:ss. empty string if null.
119
     */
120
    @NotNull
121
    public static String full19(@Nullable ZonedDateTime date) {
122
        return full19(date, null);
1✔
123
    }
124

125
    /**
126
     * Format to yyyy-MM-dd HH:mm:ss.SSS. empty string if null.
127
     */
128
    @NotNull
129
    public static String full23(@Nullable ZonedDateTime date) {
130
        return full23(date, null);
1✔
131
    }
132

133
    /**
134
     * Format to HH:mm:ss or HH:mm:ss.SSS. empty string if null.
135
     */
136
    @NotNull
137
    public static String time(@Nullable ZonedDateTime date) {
138
        if (date == null || date.getNano() > 999_999) {
1✔
139
            return time12(date, null);
1✔
140
        }
141
        else {
142
            return time08(date, null);
1✔
143
        }
144
    }
145

146
    /**
147
     * Format to HH:mm:ss. empty string if null.
148
     */
149
    @NotNull
150
    public static String time08(@Nullable ZonedDateTime date) {
151
        return time08(date, null);
1✔
152
    }
153

154
    /**
155
     * Format to HH:mm:ss.SSS. empty string if null.
156
     */
157
    @NotNull
158
    public static String time12(@Nullable ZonedDateTime date) {
159
        return time12(date, null);
1✔
160
    }
161

162
    /**
163
     * Format to yyyy-MM-dd at zoneId. empty string if null.
164
     */
165
    @NotNull
166
    public static String date10(@Nullable ZonedDateTime date, @Nullable ZoneId zoneId) {
167
        if (date == null) return "";
1✔
168
        if (zoneId != null && !zoneId.equals(date.getZone())) {
1✔
169
            date = date.withZoneSameInstant(zoneId);
1✔
170
        }
171
        return date10(date.getYear(), date.getMonthValue(), date.getDayOfMonth());
1✔
172
    }
173

174
    /**
175
     * Format to yyyy-MM-dd HH:mm:ss or yyyy-MM-dd HH:mm:ss.SSS at zoneId. empty string if null.
176
     */
177
    @NotNull
178
    public static String full(@Nullable ZonedDateTime date, @Nullable ZoneId zoneId) {
179
        if (date == null) return "";
1✔
180
        if (zoneId != null && !zoneId.equals(date.getZone())) {
1✔
181
            date = date.withZoneSameInstant(zoneId);
1✔
182
        }
183
        if (date.getNano() > 999_999) {
1✔
184
            return full23(date.getYear(), date.getMonthValue(), date.getDayOfMonth(), date.getHour(), date.getMinute(), date.getSecond(), date.getNano());
1✔
185
        }
186
        else {
187
            return full19(date.getYear(), date.getMonthValue(), date.getDayOfMonth(), date.getHour(), date.getMinute(), date.getSecond());
1✔
188
        }
189
    }
190

191
    /**
192
     * Format to yyyy-MM-dd HH:mm:ss at zoneId. empty string if null.
193
     */
194
    @NotNull
195
    public static String full19(@Nullable ZonedDateTime date, @Nullable ZoneId zoneId) {
196
        if (date == null) return "";
1✔
197
        if (zoneId != null && !zoneId.equals(date.getZone())) {
1✔
198
            date = date.withZoneSameInstant(zoneId);
1✔
199
        }
200
        return full19(date.getYear(), date.getMonthValue(), date.getDayOfMonth(), date.getHour(), date.getMinute(), date.getSecond());
1✔
201
    }
202

203
    /**
204
     * Format to yyyy-MM-dd HH:mm:ss.SSS at zoneId. empty string if null.
205
     */
206
    @NotNull
207
    public static String full23(@Nullable ZonedDateTime date, @Nullable ZoneId zoneId) {
208
        if (date == null) return "";
1✔
209
        if (zoneId != null && !zoneId.equals(date.getZone())) {
1✔
210
            date = date.withZoneSameInstant(zoneId);
1✔
211
        }
212
        return full23(date.getYear(), date.getMonthValue(), date.getDayOfMonth(), date.getHour(), date.getMinute(), date.getSecond(), date.getNano());
1✔
213
    }
214

215
    /**
216
     * Format to HH:mm:ss or HH:mm:ss.SSS at zoneId. empty string if null.
217
     */
218
    @NotNull
219
    public static String time(@Nullable ZonedDateTime date, @Nullable ZoneId zoneId) {
220
        if (date == null) return "";
1✔
221
        if (zoneId != null && !zoneId.equals(date.getZone())) {
1✔
222
            date = date.withZoneSameInstant(zoneId);
1✔
223
        }
224
        if (date.getNano() > 999_999) {
1✔
225
            return time12(date.getHour(), date.getMinute(), date.getSecond(), date.getNano());
1✔
226
        }
227
        else {
228
            return time08(date.getHour(), date.getMinute(), date.getSecond());
1✔
229
        }
230
    }
231

232
    /**
233
     * Format to HH:mm:ss at zoneId. empty string if null.
234
     */
235
    @NotNull
236
    public static String time08(@Nullable ZonedDateTime date, @Nullable ZoneId zoneId) {
237
        if (date == null) return "";
1✔
238
        if (zoneId != null && !zoneId.equals(date.getZone())) {
1✔
239
            date = date.withZoneSameInstant(zoneId);
1✔
240
        }
241
        return time08(date.getHour(), date.getMinute(), date.getSecond());
1✔
242
    }
243

244
    /**
245
     * Format to HH:mm:ss.SSS at zoneId. empty string if null.
246
     */
247
    @NotNull
248
    public static String time12(@Nullable ZonedDateTime date, @Nullable ZoneId zoneId) {
249
        if (date == null) return "";
1✔
250
        if (zoneId != null && !zoneId.equals(date.getZone())) {
1✔
251
            date = date.withZoneSameInstant(zoneId);
1✔
252
        }
253
        return time12(date.getHour(), date.getMinute(), date.getSecond(), date.getNano());
1✔
254
    }
255

256
    /**
257
     * Format to yyyy-MM-dd. empty string if null.
258
     */
259
    @NotNull
260
    public static String date10(@Nullable LocalDateTime date) {
261
        if (date == null) return "";
1✔
262
        return date10(date.getYear(), date.getMonthValue(), date.getDayOfMonth());
1✔
263
    }
264

265
    /**
266
     * Format to yyyy-MM-dd HH:mm:ss or yyyy-MM-dd HH:mm:ss.SSS. empty string if null.
267
     */
268
    @NotNull
269
    public static String full(@Nullable LocalDateTime date) {
270
        if (date == null) return "";
1✔
271
        if (date.getNano() > 999_999) {
1✔
272
            return full23(date.getYear(), date.getMonthValue(), date.getDayOfMonth(), date.getHour(), date.getMinute(), date.getSecond(), date.getNano());
1✔
273
        }
274
        else {
275
            return full19(date.getYear(), date.getMonthValue(), date.getDayOfMonth(), date.getHour(), date.getMinute(), date.getSecond());
1✔
276
        }
277
    }
278

279
    /**
280
     * Format to yyyy-MM-dd HH:mm:ss. empty string if null.
281
     */
282
    @NotNull
283
    public static String full19(@Nullable LocalDateTime date) {
284
        if (date == null) return "";
1✔
285
        return full19(date.getYear(), date.getMonthValue(), date.getDayOfMonth(), date.getHour(), date.getMinute(), date.getSecond());
1✔
286
    }
287

288
    /**
289
     * Format to yyyy-MM-dd HH:mm:ss.SSS. empty string if null.
290
     */
291
    @NotNull
292
    public static String full23(@Nullable LocalDateTime date) {
293
        if (date == null) return "";
1✔
294
        return full23(date.getYear(), date.getMonthValue(), date.getDayOfMonth(), date.getHour(), date.getMinute(), date.getSecond(), date.getNano());
1✔
295
    }
296

297
    /**
298
     * Format to HH:mm:ss or HH:mm:ss.SSS. empty string if null.
299
     */
300
    @NotNull
301
    public static String time(@Nullable LocalDateTime date) {
302
        if (date == null) return "";
1✔
303
        if (date.getNano() > 999_999) {
1✔
304
            return time12(date.getHour(), date.getMinute(), date.getSecond(), date.getNano());
1✔
305
        }
306
        else {
307
            return time08(date.getHour(), date.getMinute(), date.getSecond());
1✔
308
        }
309
    }
310

311
    /**
312
     * Format to HH:mm:ss. empty string if null.
313
     */
314
    @NotNull
315
    public static String time08(@Nullable LocalDateTime date) {
316
        if (date == null) return "";
1✔
317
        return time08(date.getHour(), date.getMinute(), date.getSecond());
1✔
318
    }
319

320
    /**
321
     * Format to HH:mm:ss.SSS. empty string if null.
322
     */
323
    @NotNull
324
    public static String time12(@Nullable LocalDateTime date) {
325
        if (date == null) return "";
1✔
326
        return time12(date.getHour(), date.getMinute(), date.getSecond(), date.getNano());
1✔
327
    }
328

329

330
    /**
331
     * Format to yyyy-MM-dd. empty string if null.
332
     */
333
    @NotNull
334
    public static String date10(@Nullable LocalDate date) {
335
        if (date == null) return "";
1✔
336
        return date10(date.getYear(), date.getMonthValue(), date.getDayOfMonth());
1✔
337
    }
338

339
    /**
340
     * Format to HH:mm:ss or HH:mm:ss.SSS. empty string if null.
341
     */
342
    @NotNull
343
    public static String time(@Nullable LocalTime time) {
344
        if (time == null) return "";
1✔
345
        if (time.getNano() > 999_999) {
1✔
346
            return time12(time.getHour(), time.getMinute(), time.getSecond(), time.getNano());
1✔
347
        }
348
        else {
349
            return time08(time.getHour(), time.getMinute(), time.getSecond());
1✔
350
        }
351
    }
352

353
    /**
354
     * Format to HH:mm:ss. empty string if null.
355
     */
356
    @NotNull
357
    public static String time08(@Nullable LocalTime time) {
358
        if (time == null) return "";
1✔
359
        return time08(time.getHour(), time.getMinute(), time.getSecond());
1✔
360
    }
361

362
    /**
363
     * Format to HH:mm:ss.SSS. empty string if null.
364
     */
365
    @NotNull
366
    public static String time12(@Nullable LocalTime time) {
367
        if (time == null) return "";
1✔
368
        return time12(time.getHour(), time.getMinute(), time.getSecond(), time.getNano());
1✔
369
    }
370

371

372
    /**
373
     * Format to yyyy-MM-dd. empty string if null.
374
     */
375
    @NotNull
376
    public static String date10(@Nullable Date date) {
377
        return full19().format(date).substring(0, 10);
1✔
378
    }
379

380
    /**
381
     * Format to yyyy-MM-dd HH:mm:ss or yyyy-MM-dd HH:mm:ss.SSS. empty string if null.
382
     */
383
    @NotNull
384
    public static String full(@Nullable Date date) {
385
        final String ft = full23().format(date);
1✔
386
        if (ft.endsWith(".000")) {
1✔
387
            return ft.substring(0, 19);
×
388
        }
389
        else {
390
            return ft;
1✔
391
        }
392
    }
393

394
    /**
395
     * Format to yyyy-MM-dd HH:mm:ss. empty string if null.
396
     */
397
    @NotNull
398
    public static String full19(@Nullable Date date) {
399
        return full19().format(date);
1✔
400
    }
401

402
    /**
403
     * Format to yyyy-MM-dd HH:mm:ss.SSS. empty string if null.
404
     */
405
    @NotNull
406
    public static String full23(@Nullable Date date) {
407
        return full23().format(date);
1✔
408
    }
409

410
    /**
411
     * Format to HH:mm:ss or HH:mm:ss.SSS. empty string if null.
412
     */
413
    @NotNull
414
    public static String time(@Nullable Date date) {
415
        final String ft = full23().format(date);
1✔
416
        if (ft.endsWith(".000")) {
1✔
417
            return ft.substring(11, 19);
1✔
418
        }
419
        else {
420
            return ft.substring(11);
1✔
421
        }
422
    }
423

424
    /**
425
     * Format to HH:mm:ss. empty string if null.
426
     */
427
    @NotNull
428
    public static String time08(@Nullable Date date) {
429
        return full19().format(date).substring(11);
1✔
430
    }
431

432
    /**
433
     * Format to HH:mm:ss.SSS. empty string if null.
434
     */
435
    @NotNull
436
    public static String time12(@Nullable Date date) {
437
        return full23().format(date).substring(11);
1✔
438
    }
439

440

441
    /**
442
     * Format to yyyy-MM-dd at zoneId. empty string if null.
443
     */
444
    @NotNull
445
    public static String date10(@Nullable Date date, @Nullable ZoneId zoneId) {
446
        if (date == null) return "";
1✔
447
        ZonedDateTime dateTime = zoned(date, zoneId);
1✔
448
        return date10(dateTime, null);
1✔
449
    }
450

451
    /**
452
     * Format to yyyy-MM-dd HH:mm:ss or yyyy-MM-dd HH:mm:ss.SSS at zoneId. empty string if null.
453
     */
454
    @NotNull
455
    public static String full(@Nullable Date date, @Nullable ZoneId zoneId) {
456
        if (date == null) return "";
1✔
457
        ZonedDateTime dateTime = zoned(date, zoneId);
1✔
458
        if (dateTime.getNano() > 999_999) {
1✔
459
            return full23(dateTime, null);
1✔
460
        }
461
        else {
462
            return full19(dateTime, null);
×
463
        }
464
    }
465

466
    /**
467
     * Format to yyyy-MM-dd HH:mm:ss at zoneId. empty string if null.
468
     */
469
    @NotNull
470
    public static String full19(@Nullable Date date, @Nullable ZoneId zoneId) {
471
        if (date == null) return "";
1✔
472
        ZonedDateTime dateTime = zoned(date, zoneId);
1✔
473
        return full19(dateTime, null);
1✔
474
    }
475

476
    /**
477
     * Format to yyyy-MM-dd HH:mm:ss.SSS at zoneId. empty string if null.
478
     */
479
    @NotNull
480
    public static String full23(@Nullable Date date, @Nullable ZoneId zoneId) {
481
        if (date == null) return "";
1✔
482
        ZonedDateTime dateTime = zoned(date, zoneId);
1✔
483
        return full23(dateTime, null);
1✔
484
    }
485

486
    /**
487
     * Format to HH:mm:ss or HH:mm:ss.SSS at zoneId. empty string if null.
488
     */
489
    @NotNull
490
    public static String time(@Nullable Date date, @Nullable ZoneId zoneId) {
491
        if (date == null) return "";
1✔
492
        ZonedDateTime dateTime = zoned(date, zoneId);
1✔
493
        return time(dateTime, null);
1✔
494
    }
495

496
    /**
497
     * Format to HH:mm:ss at zoneId. empty string if null.
498
     */
499
    @NotNull
500
    public static String time08(@Nullable Date date, @Nullable ZoneId zoneId) {
501
        if (date == null) return "";
1✔
502
        ZonedDateTime dateTime = zoned(date, zoneId);
1✔
503
        return time08(dateTime, null);
1✔
504
    }
505

506
    /**
507
     * Format to HH:mm:ss.SSS at zoneId. empty string if null.
508
     */
509
    @NotNull
510
    public static String time12(@Nullable Date date, @Nullable ZoneId zoneId) {
511
        if (date == null) return "";
1✔
512
        ZonedDateTime dateTime = zoned(date, zoneId);
1✔
513
        return time12(dateTime, null);
1✔
514
    }
515

516
    /**
517
     * convert date at zoneId
518
     */
519
    @NotNull
520
    public static ZonedDateTime zoned(@NotNull Date date, @Nullable ZoneId zoneId) {
521
        if (zoneId == null) {
1✔
522
            return date.toInstant().atZone(ThreadNow.sysZoneId());
1✔
523
        }
524
        else {
525
            return date.toInstant().atZone(zoneId);
1✔
526
        }
527
    }
528

529
    /**
530
     * <pre>
531
     * Guarantee consistency, i.e. the same string, returns consistent results.
532
     * Fix date string to yyyy-MM-dd HH:mm:ss
533
     * `HH`, `MM`, `ss` are pseudo-randomly generated based on `yyyy-MM-dd`,
534
     * which defaults to `1979-01-01`, respectively.
535
     * </pre>
536
     *
537
     * @param date Any date containing numbers, will automatically fix the hours, minutes and seconds.
538
     * @return Fixed date.
539
     */
540
    @NotNull
541
    public static String fixFull19(@Nullable String date) {
542
        if (date == null) return "1979-01-01";
1✔
543

544
        int len = date.length();
1✔
545
        StringBuilder tmp = new StringBuilder(len);
1✔
546
        int seed = 0;
1✔
547
        for (int i = 0; i < len; i++) {
1✔
548
            char c = HalfCharUtil.half(date.charAt(i));
1✔
549
            if (c >= '0' && c <= '9') {
1✔
550
                tmp.append(c);
1✔
551
                seed = 31 * seed + c;
1✔
552
            }
553
            else {
554
                tmp.append(' ');
1✔
555
            }
556
        }
557

558
        StringBuilder buf = new StringBuilder(19);
1✔
559
        int[] idx = new int[]{ 0, 0 };
1✔
560

561
        // yyyy-MM-dd
562
        fillDigit(tmp, 4, idx, buf, 1970, '-');
1✔
563
        fillDigit(tmp, 2, idx, buf, 1, '-');
1✔
564
        fillDigit(tmp, 2, idx, buf, 1, ' ');
1✔
565

566
        if (seed < 0) {
1✔
567
            seed = seed >>> 1;
1✔
568
        }
569

570
        int h = seed % 24;
1✔
571
        int m = seed % 60;
1✔
572
        int s = (seed & 0xFF) % 60;
1✔
573

574
        // HH:mm:ss
575
        fillDigit(tmp, 2, idx, buf, h, ':');
1✔
576
        fillDigit(tmp, 2, idx, buf, m, ':');
1✔
577
        fillDigit(tmp, 2, idx, buf, s, '\0');
1✔
578

579
        return buf.toString();
1✔
580
    }
581

582
    private static void fillDigit(CharSequence str, int max, int[] idx, StringBuilder buf, int nil, char end) {
583
        // get digit
584
        if (idx[1] >= 0) {
1✔
585
            int cnt = 0;
1✔
586
            int off = idx[1];
1✔
587
            idx[1] = -1;
1✔
588
            int len = str.length();
1✔
589
            for (int i = off; i < len; i++) {
1✔
590
                char c = str.charAt(i);
1✔
591
                if (c >= '0' && c <= '9') {
1✔
592
                    if (cnt == 0) {
1✔
593
                        idx[0] = i;
1✔
594
                    }
595
                    idx[1] = i;
1✔
596
                    cnt++;
1✔
597
                }
598
                else {
599
                    if (cnt > 0) {
1✔
600
                        cnt = max; // reach the max
×
601
                    }
602
                }
603
                if (cnt >= max) {
1✔
604
                    break;
1✔
605
                }
606
            }
607
            if (idx[1] > 0) {
1✔
608
                idx[1] = idx[1] + 1;
1✔
609
            }
610
        }
611

612
        // padding
613
        int len = idx[1] - idx[0];
1✔
614
        if (idx[1] > 0 && len > 0) {
1✔
615
            for (int i = len; i < max; i++) {
1✔
616
                buf.append('0');
1✔
617
            }
618
            buf.append(str, idx[0], idx[1]);
1✔
619
        }
620
        else {
621
            String s = String.valueOf(nil);
1✔
622
            for (int i = s.length(); i < max; i++) {
1✔
623
                buf.append('0');
1✔
624
            }
625
            buf.append(s);
1✔
626
        }
627
        if (end > 0) {
1✔
628
            buf.append(end);
1✔
629
        }
630
    }
1✔
631

632
    private static String full19(int y, int m, int d, int h, int i, int s) {
633
        StringBuilder sb = new StringBuilder(19);
1✔
634
        fixDate10(sb, y, m, d);
1✔
635
        sb.append(' ');
1✔
636
        fixTime08(sb, h, i, s);
1✔
637
        return sb.toString();
1✔
638
    }
639

640
    private static String full23(int y, int m, int d, int h, int i, int s, int n) {
641
        StringBuilder sb = new StringBuilder(19);
1✔
642
        fixDate10(sb, y, m, d);
1✔
643
        sb.append(' ');
1✔
644
        fixTime08(sb, h, i, s);
1✔
645
        fixNano(sb, n);
1✔
646
        return sb.toString();
1✔
647
    }
648

649
    private static String date10(int y, int m, int d) {
650
        StringBuilder sb = new StringBuilder(10);
1✔
651
        fixDate10(sb, y, m, d);
1✔
652
        return sb.toString();
1✔
653
    }
654

655
    private static String time08(int h, int m, int s) {
656
        StringBuilder sb = new StringBuilder(8);
1✔
657
        fixTime08(sb, h, m, s);
1✔
658
        return sb.toString();
1✔
659
    }
660

661
    private static String time12(int h, int m, int s, int n) {
662
        StringBuilder sb = new StringBuilder(8);
1✔
663
        fixTime08(sb, h, m, s);
1✔
664
        fixNano(sb, n);
1✔
665
        return sb.toString();
1✔
666
    }
667

668
    private static void fixDate10(StringBuilder buf, int y, int m, int d) {
669
        buf.append(y).append('-');
1✔
670
        if (m < 10) buf.append('0');
1✔
671
        buf.append(m).append('-');
1✔
672
        if (d < 10) buf.append('0');
1✔
673
        buf.append(d);
1✔
674
    }
1✔
675

676
    private static void fixTime08(StringBuilder buf, int h, int m, int s) {
677
        if (h < 10) buf.append('0');
1✔
678
        buf.append(h).append(':');
1✔
679
        if (m < 10) buf.append('0');
1✔
680
        buf.append(m).append(':');
1✔
681
        if (s < 10) buf.append('0');
1✔
682
        buf.append(s);
1✔
683
    }
1✔
684

685
    private static void fixNano(StringBuilder buf, int n) {
686
        buf.append('.');
1✔
687
        // the nano-of-second, from 0 to 999,999,999
688
        int s = n / 1_000_000;
1✔
689
        if (s < 10) buf.append('0');
1✔
690
        if (s < 100) buf.append('0');
1✔
691
        buf.append(s);
1✔
692
    }
1✔
693
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc