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

azjezz / psl / 17432557268

03 Sep 2025 11:52AM UTC coverage: 98.446% (-0.07%) from 98.513%
17432557268

push

github

web-flow
chore: migrate from `psalm` to `mago` (#527)

232 of 241 new or added lines in 81 files covered. (96.27%)

14 existing lines in 12 files now uncovered.

5510 of 5597 relevant lines covered (98.45%)

52.23 hits per line

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

99.28
/src/Psl/DateTime/Duration.php
1
<?php
2

3
declare(strict_types=1);
4

5
namespace Psl\DateTime;
6

7
use JsonSerializable;
8
use Psl\Comparison;
9
use Psl\Math;
10
use Psl\Str;
11
use Stringable;
12

13
/**
14
 * Defines a representation of a time duration with specific hours, minutes, seconds,
15
 * and nanoseconds.
16
 *
17
 * All instances are normalized as follows:
18
 *
19
 * - all non-zero parts (hours, minutes, seconds, nanoseconds) will have the same sign
20
 * - minutes, seconds will be between -59 and 59
21
 * - nanoseconds will be between -999999999 and 999999999 (less than 1 second)
22
 *
23
 * For example, Duration::hours(2, -183) normalizes to "-1 hour(s), -3 minute(s)".
24
 *
25
 * @implements Comparison\Comparable<Duration>
26
 * @implements Comparison\Equable<Duration>
27
 *
28
 * @immutable
29
 */
30
final readonly class Duration implements Comparison\Comparable, Comparison\Equable, JsonSerializable, Stringable
31
{
32
    /**
33
     * Initializes a new instance of Duration with specified hours, minutes, seconds, and
34
     * nanoseconds.
35
     *
36
     * @param int $hours
37
     * @param int<-59, 59> $minutes
38
     * @param int<-59, 59> $seconds
39
     * @param int<-999999999, 999999999> $nanoseconds
40
     *
41
     * @pure
42
     */
43
    private function __construct(
44
        private int $hours,
45
        private int $minutes,
46
        private int $seconds,
47
        private int $nanoseconds,
48
    ) {}
145✔
49

50
    /**
51
     * Returns an instance representing the specified number of hours (and
52
     * optionally minutes, seconds, nanoseconds). Due to normalization, the
53
     * actual values in the returned instance may differ from the provided ones.
54
     *
55
     * @pure
56
     *
57
     * @mago-expect lint:best-practices/no-else-clause
58
     */
59
    public static function fromParts(int $hours, int $minutes = 0, int $seconds = 0, int $nanoseconds = 0): self
60
    {
61
        // This is where the normalization happens.
62
        $s =
145✔
63
            (SECONDS_PER_HOUR * $hours)
145✔
64
            + (SECONDS_PER_MINUTE * $minutes)
145✔
65
            + $seconds
145✔
66
            + (int) ($nanoseconds / NANOSECONDS_PER_SECOND);
145✔
67
        $ns = $nanoseconds % NANOSECONDS_PER_SECOND;
145✔
68
        if ($s < 0 && $ns > 0) {
145✔
69
            ++$s;
3✔
70
            $ns -= NANOSECONDS_PER_SECOND;
3✔
71
        } elseif ($s > 0 && $ns < 0) {
144✔
72
            --$s;
3✔
73
            $ns += NANOSECONDS_PER_SECOND;
3✔
74
        }
75

76
        $m = (int) ($s / 60);
145✔
77
        $s %= 60;
145✔
78
        $h = (int) ($m / 60);
145✔
79
        $m %= 60;
145✔
80
        return new self($h, $m, $s, $ns);
145✔
81
    }
82

83
    /**
84
     * Returns an instance representing the specified number of weeks, in hours.
85
     *
86
     * For example, `Duration::weeks(1)` is equivalent to `Duration::hours(168)`.
87
     *
88
     * @pure
89
     */
90
    public static function weeks(int $weeks): self
91
    {
92
        return self::fromParts($weeks * HOURS_PER_WEEK);
1✔
93
    }
94

95
    /**
96
     * Returns an instance representing the specified number of days, in hours.
97
     *
98
     * For example, `Duration::days(2)` is equivalent to `Duration::hours(48)`.
99
     *
100
     * @pure
101
     */
102
    public static function days(int $days): self
103
    {
104
        return self::fromParts($days * HOURS_PER_DAY);
3✔
105
    }
106

107
    /**
108
     * Returns an instance representing the specified number of hours.
109
     *
110
     * @pure
111
     */
112
    public static function hours(int $hours): self
113
    {
114
        return self::fromParts($hours);
6✔
115
    }
116

117
    /**
118
     * Returns an instance representing the specified number of minutes. Due to
119
     * normalization, the actual value in the returned instance may differ from
120
     * the provided one, and the resulting instance may contain larger units.
121
     *
122
     * For example, `Duration::minutes(63)` normalizes to "1 hour(s), 3 minute(s)".
123
     *
124
     * @pure
125
     */
126
    public static function minutes(int $minutes): self
127
    {
128
        return self::fromParts(0, $minutes);
6✔
129
    }
130

131
    /**
132
     * Returns an instance representing the specified number of seconds. Due to
133
     * normalization, the actual value in the returned instance may differ from
134
     * the provided one, and the resulting instance may contain larger units.
135
     *
136
     * For example, `Duration::seconds(63)` normalizes to "1 minute(s), 3 second(s)".
137
     *
138
     * @pure
139
     */
140
    public static function seconds(int $seconds): self
141
    {
142
        return self::fromParts(0, 0, $seconds);
5✔
143
    }
144

145
    /**
146
     * Returns an instance representing the specified number of milliseconds (ms).
147
     * The value is converted and stored as nanoseconds, since that is the only
148
     * unit smaller than a second that we support. Due to normalization, the
149
     * resulting instance may contain larger units.
150
     *
151
     * For example, `Duration::milliseconds(8042)` normalizes to "8 second(s), 42000000 nanosecond(s)".
152
     *
153
     * @pure
154
     */
155
    public static function milliseconds(int $milliseconds): self
156
    {
157
        return self::fromParts(0, 0, 0, NANOSECONDS_PER_MILLISECOND * $milliseconds);
62✔
158
    }
159

160
    /**
161
     * Returns an instance representing the specified number of microseconds (us).
162
     * The value is converted and stored as nanoseconds, since that is the only
163
     * unit smaller than a second that we support. Due to normalization, the
164
     * resulting instance may contain larger units.
165
     *
166
     * For example, `Duration::microseconds(8000042)` normalizes to "8 second(s), 42000 nanosecond(s)".
167
     *
168
     * @pure
169
     */
170
    public static function microseconds(int $microseconds): self
171
    {
172
        return self::fromParts(0, 0, 0, NANOSECONDS_PER_MICROSECOND * $microseconds);
4✔
173
    }
174

175
    /**
176
     * Returns an instance representing the specified number of nanoseconds (ns).
177
     * Due to normalization, the resulting instance may contain larger units.
178
     *
179
     * For example, `Duration::nanoseconds(8000000042)` normalizes to "8 second(s), 42 nanosecond(s)".
180
     *
181
     * @pure
182
     */
183
    public static function nanoseconds(int $nanoseconds): self
184
    {
185
        return self::fromParts(0, 0, 0, $nanoseconds);
6✔
186
    }
187

188
    /**
189
     * Returns an instance with all parts equal to 0.
190
     *
191
     * @pure
192
     */
193
    public static function zero(): self
194
    {
195
        return new self(0, 0, 0, 0);
3✔
196
    }
197

198
    /**
199
     * Compiles and returns the duration's components (hours, minutes, seconds, nanoseconds) in an
200
     * array, in descending order of significance.
201
     *
202
     * @return array{int, int, int, int}
203
     *
204
     * @psalm-mutation-free
205
     */
206
    public function getParts(): array
207
    {
208
        return [$this->hours, $this->minutes, $this->seconds, $this->nanoseconds];
22✔
209
    }
210

211
    /**
212
     * Returns the "hours" part of this time duration.
213
     *
214
     * @psalm-mutation-free
215
     */
216
    public function getHours(): int
217
    {
218
        return $this->hours;
1✔
219
    }
220

221
    /**
222
     * Returns the "minutes" part of this time duration.
223
     *
224
     * @psalm-mutation-free
225
     */
226
    public function getMinutes(): int
227
    {
228
        return $this->minutes;
1✔
229
    }
230

231
    /**
232
     * Returns the "seconds" part of this time duration.
233
     *
234
     * @psalm-mutation-free
235
     */
236
    public function getSeconds(): int
237
    {
238
        return $this->seconds;
2✔
239
    }
240

241
    /**
242
     * Returns the "nanoseconds" part of this time duration.
243
     *
244
     * @psalm-mutation-free
245
     */
246
    public function getNanoseconds(): int
247
    {
248
        return $this->nanoseconds;
3✔
249
    }
250

251
    /**
252
     * Computes, and returns the total duration of the instance in hours as a floating-point number,
253
     * including any fractional parts.
254
     *
255
     * @psalm-mutation-free
256
     */
257
    public function getTotalHours(): float
258
    {
259
        return (
11✔
260
            $this->hours
11✔
261
            + ($this->minutes / MINUTES_PER_HOUR)
11✔
262
            + ($this->seconds / SECONDS_PER_HOUR)
11✔
263
            + ($this->nanoseconds / (SECONDS_PER_HOUR * NANOSECONDS_PER_SECOND))
11✔
264
        );
11✔
265
    }
266

267
    /**
268
     * Computes, and returns the total duration of the instance in minutes as a floating-point number,
269
     * including any fractional parts.
270
     *
271
     * @psalm-mutation-free
272
     */
273
    public function getTotalMinutes(): float
274
    {
275
        return (
9✔
276
            ($this->hours * MINUTES_PER_HOUR)
9✔
277
            + $this->minutes
9✔
278
            + ($this->seconds / SECONDS_PER_MINUTE)
9✔
279
            + ($this->nanoseconds / (SECONDS_PER_MINUTE * NANOSECONDS_PER_SECOND))
9✔
280
        );
9✔
281
    }
282

283
    /**
284
     * Computes, and returns the total duration of the instance in seconds as a floating-point number,
285
     * including any fractional parts.
286
     *
287
     * @psalm-mutation-free
288
     */
289
    public function getTotalSeconds(): float
290
    {
291
        return (
67✔
292
            $this->seconds
67✔
293
            + ($this->minutes * SECONDS_PER_MINUTE)
67✔
294
            + ($this->hours * SECONDS_PER_HOUR)
67✔
295
            + ($this->nanoseconds / NANOSECONDS_PER_SECOND)
67✔
296
        );
67✔
297
    }
298

299
    /**
300
     * Computes, and returns the total duration of the instance in milliseconds as a floating-point number,
301
     * including any fractional parts.
302
     *
303
     * @psalm-mutation-free
304
     */
305
    public function getTotalMilliseconds(): float
306
    {
307
        return (
10✔
308
            ($this->hours * SECONDS_PER_HOUR * MILLISECONDS_PER_SECOND)
10✔
309
            + ($this->minutes * SECONDS_PER_MINUTE * MILLISECONDS_PER_SECOND)
10✔
310
            + ($this->seconds * MILLISECONDS_PER_SECOND)
10✔
311
            + ($this->nanoseconds / NANOSECONDS_PER_MILLISECOND)
10✔
312
        );
10✔
313
    }
314

315
    /**
316
     * Computes, and returns the total duration of the instance in microseconds as a floating-point number,
317
     * including any fractional parts.
318
     *
319
     * @psalm-mutation-free
320
     */
321
    public function getTotalMicroseconds(): float
322
    {
323
        return (
9✔
324
            ($this->hours * SECONDS_PER_HOUR * MICROSECONDS_PER_SECOND)
9✔
325
            + ($this->minutes * SECONDS_PER_MINUTE * MICROSECONDS_PER_SECOND)
9✔
326
            + ($this->seconds * MICROSECONDS_PER_SECOND)
9✔
327
            + ($this->nanoseconds / NANOSECONDS_PER_MICROSECOND)
9✔
328
        );
9✔
329
    }
330

331
    /**
332
     * Determines whether the instance represents a zero duration.
333
     *
334
     * @psalm-mutation-free
335
     */
336
    public function isZero(): bool
337
    {
338
        return $this->hours === 0 && $this->minutes === 0 && $this->seconds === 0 && $this->nanoseconds === 0;
6✔
339
    }
340

341
    /**
342
     * Checks if the duration is positive, implying that all non-zero components are positive.
343
     *
344
     * Due to normalization, it is guaranteed that a positive time duration will
345
     * have all of its parts (hours, minutes, seconds, nanoseconds) positive or
346
     * equal to 0.
347
     *
348
     * Note that this method returns false if all parts are equal to 0.
349
     *
350
     * @psalm-mutation-free
351
     */
352
    public function isPositive(): bool
353
    {
354
        return $this->hours > 0 || $this->minutes > 0 || $this->seconds > 0 || $this->nanoseconds > 0;
5✔
355
    }
356

357
    /**
358
     * Checks if the duration is negative, implying that all non-zero components are negative.
359
     *
360
     * Due to normalization, it is guaranteed that a negative time duration will
361
     * have all of its parts (hours, minutes, seconds, nanoseconds) negative or
362
     * equal to 0.
363
     *
364
     * Note that this method returns false if all parts are equal to 0.
365
     *
366
     * @psalm-mutation-free
367
     */
368
    public function isNegative(): bool
369
    {
370
        return $this->hours < 0 || $this->minutes < 0 || $this->seconds < 0 || $this->nanoseconds < 0;
4✔
371
    }
372

373
    /**
374
     * Returns a new instance with the "hours" part changed to the specified
375
     * value.
376
     *
377
     * Note that due to normalization, the actual value in the returned
378
     * instance may differ, and this may affect other parts of the returned
379
     * instance too.
380
     *
381
     * For example, `Duration::hours(2, 30)->withHours(-1)` is equivalent to
382
     * `Duration::hours(-1, 30)` which normalizes to "-30 minute(s)".
383
     *
384
     * @psalm-mutation-free
385
     */
386
    public function withHours(int $hours): self
387
    {
388
        return self::fromParts($hours, $this->minutes, $this->seconds, $this->nanoseconds);
1✔
389
    }
390

391
    /**
392
     * Returns a new instance with the "minutes" part changed to the specified
393
     * value.
394
     *
395
     * Note that due to normalization, the actual value in the returned
396
     * instance may differ, and this may affect other parts of the returned
397
     * instance too.
398
     *
399
     * For example, `Duration::minutes(2, 30)->withMinutes(-1)` is equivalent to
400
     * `Duration::minutes(-1, 30)` which normalizes to "-30 second(s)".
401
     *
402
     * @psalm-mutation-free
403
     */
404
    public function withMinutes(int $minutes): self
405
    {
406
        return self::fromParts($this->hours, $minutes, $this->seconds, $this->nanoseconds);
1✔
407
    }
408

409
    /**
410
     * Returns a new instance with the "seconds" part changed to the specified
411
     * value.
412
     *
413
     * Note that due to normalization, the actual value in the returned
414
     * instance may differ, and this may affect other parts of the returned
415
     * instance too.
416
     *
417
     * For example, `Duration::minutes(2, 30)->withSeconds(-30)` is equivalent
418
     * to `Duration::minutes(2, -30)` which normalizes to "1 minute(s), 30 second(s)".
419
     *
420
     * @psalm-mutation-free
421
     */
422
    public function withSeconds(int $seconds): self
423
    {
424
        return self::fromParts($this->hours, $this->minutes, $seconds, $this->nanoseconds);
1✔
425
    }
426

427
    /**
428
     * Returns a new instance with the "nanoseconds" part changed to the specified
429
     * value.
430
     *
431
     * Note that due to normalization, the actual value in the returned
432
     * instance may differ, and this may affect other parts of the returned
433
     * instance too.
434
     *
435
     * For example, `Duration::seconds(2)->withNanoseconds(-1)` is equivalent
436
     * to `Duration::seconds(2, -1)` which normalizes to "1 second(s), 999999999 nanosecond(s)".
437
     *
438
     * @psalm-mutation-free
439
     */
440
    public function withNanoseconds(int $nanoseconds): self
441
    {
442
        return self::fromParts($this->hours, $this->minutes, $this->seconds, $nanoseconds);
1✔
443
    }
444

445
    /**
446
     * Implements a comparison between this duration and another, based on their duration.
447
     *
448
     * @param Duration $other
449
     *
450
     * @psalm-mutation-free
451
     */
452
    #[\Override]
453
    public function compare(mixed $other): Comparison\Order
454
    {
455
        if ($this->hours !== $other->hours) {
7✔
456
            return Comparison\Order::from($this->hours <=> $other->hours);
1✔
457
        }
458

459
        if ($this->minutes !== $other->minutes) {
7✔
460
            return Comparison\Order::from($this->minutes <=> $other->minutes);
1✔
461
        }
462

463
        if ($this->seconds !== $other->seconds) {
6✔
464
            return Comparison\Order::from($this->seconds <=> $other->seconds);
2✔
465
        }
466

467
        return Comparison\Order::from($this->nanoseconds <=> $other->nanoseconds);
6✔
468
    }
469

470
    /**
471
     * Evaluates whether this duration is equivalent to another, considering all time components.
472
     *
473
     * @param Duration $other
474
     *
475
     * @psalm-mutation-free
476
     */
477
    #[\Override]
478
    public function equals(mixed $other): bool
479
    {
480
        return $this->compare($other) === Comparison\Order::Equal;
6✔
481
    }
482

483
    /**
484
     * Determines if this duration is shorter than another.
485
     *
486
     * @psalm-mutation-free
487
     */
488
    public function shorter(self $other): bool
489
    {
490
        return $this->compare($other) === Comparison\Order::Less;
6✔
491
    }
492

493
    /**
494
     * Determines if this duration is shorter than, or equivalent to another.
495
     *
496
     * @psalm-mutation-free
497
     */
498
    public function shorterOrEqual(self $other): bool
499
    {
500
        return $this->compare($other) !== Comparison\Order::Greater;
6✔
501
    }
502

503
    /**
504
     * Determines if this duration is longer than another.
505
     *
506
     * @psalm-mutation-free
507
     */
508
    public function longer(self $other): bool
509
    {
510
        return $this->compare($other) === Comparison\Order::Greater;
6✔
511
    }
512

513
    /**
514
     * Determines if this duration is longer than, or equivalent to another.
515
     *
516
     * @psalm-mutation-free
517
     */
518
    public function longerOrEqual(self $other): bool
519
    {
520
        return $this->compare($other) !== Comparison\Order::Less;
6✔
521
    }
522

523
    /**
524
     * Returns true if this instance represents a time duration longer than $a but
525
     * shorter than $b, or vice-versa (shorter than $a but longer than $b), or if
526
     * this instance is equal to $a and/or $b. Returns false if this instance is
527
     * shorter/longer than both.
528
     *
529
     * @psalm-mutation-free
530
     */
531
    public function betweenInclusive(self $a, self $b): bool
532
    {
533
        $ca = $this->compare($a);
7✔
534
        $cb = $this->compare($b);
7✔
535

536
        return $ca === Comparison\Order::Equal || $ca !== $cb;
7✔
537
    }
538

539
    /**
540
     * Returns true if this instance represents a time duration longer than $a but
541
     * shorter than $b, or vice-versa (shorter than $a but longer than $b).
542
     * Returns false if this instance is equal to $a and/or $b, or shorter/longer
543
     * than both.
544
     *
545
     * @psalm-mutation-free
546
     */
547
    public function betweenExclusive(self $a, self $b): bool
548
    {
549
        $ca = $this->compare($a);
7✔
550
        $cb = $this->compare($b);
7✔
551

552
        return $ca !== Comparison\Order::Equal && $cb !== Comparison\Order::Equal && $ca !== $cb;
7✔
553
    }
554

555
    /**
556
     * Returns a new instance, converting a positive/negative duration to the
557
     * opposite (negative/positive) duration of equal length. The resulting
558
     * instance has all parts equivalent to the current instance's parts
559
     * multiplied by -1.
560
     *
561
     * @psalm-mutation-free
562
     */
563
    public function invert(): self
564
    {
565
        if ($this->isZero()) {
1✔
566
            return $this;
1✔
567
        }
568

569
        return new self(-$this->hours, -$this->minutes, -$this->seconds, -$this->nanoseconds);
1✔
570
    }
571

572
    /**
573
     * Returns a new instance representing the sum of this instance and the
574
     * provided `$other` instance. Note that time duration can be negative, so
575
     * the resulting instance is not guaranteed to be shorter/longer than either
576
     * of the inputs.
577
     *
578
     * This operation is commutative: `$a->plus($b) === $b->plus($a)`
579
     *
580
     * @psalm-mutation-free
581
     */
582
    public function plus(self $other): self
583
    {
584
        if ($other->isZero()) {
1✔
585
            return $this;
1✔
586
        }
587

588
        if ($this->isZero()) {
1✔
589
            return $other;
1✔
590
        }
591

592
        return self::fromParts(
1✔
593
            $this->hours + $other->hours,
1✔
594
            $this->minutes + $other->minutes,
1✔
595
            $this->seconds + $other->seconds,
1✔
596
            $this->nanoseconds + $other->nanoseconds,
1✔
597
        );
1✔
598
    }
599

600
    /**
601
     * Returns a new instance representing the difference between this instance
602
     * and the provided `$other` instance (i.e. `$other` subtracted from `$this`).
603
     * Note that time duration can be negative, so the resulting instance is not
604
     * guaranteed to be shorter/longer than either of the inputs.
605
     *
606
     * This operation is not commutative: `$a->minus($b) !== $b->minus($a)`
607
     * But: `$a->minus($b) === $b->minus($a)->invert()`
608
     *
609
     * @psalm-mutation-free
610
     */
611
    public function minus(self $other): self
612
    {
613
        if ($other->isZero()) {
1✔
614
            return $this;
1✔
615
        }
616

617
        if ($this->isZero()) {
1✔
618
            return $other->invert();
1✔
619
        }
620

621
        return self::fromParts(
1✔
622
            $this->hours - $other->hours,
1✔
623
            $this->minutes - $other->minutes,
1✔
624
            $this->seconds - $other->seconds,
1✔
625
            $this->nanoseconds - $other->nanoseconds,
1✔
626
        );
1✔
627
    }
628

629
    /**
630
     * Returns the time duration as string, useful e.g. for debugging. This is not
631
     * meant to be a comprehensive way to format time durations for user-facing
632
     * output.
633
     *
634
     * @param int<0, max> $max_decimals
635
     *
636
     * @psalm-mutation-free
637
     */
638
    public function toString(int $max_decimals = 3): string
639
    {
640
        $decimal_part = '';
15✔
641
        if ($max_decimals > 0) {
15✔
642
            $decimal_part = (string) Math\abs($this->nanoseconds);
15✔
643
            $decimal_part = Str\pad_left($decimal_part, 9, '0');
15✔
644
            $decimal_part = Str\slice($decimal_part, 0, $max_decimals);
15✔
645
            $decimal_part = Str\trim_right($decimal_part, '0');
15✔
646
        }
647

648
        if ($decimal_part !== '') {
15✔
649
            $decimal_part = '.' . $decimal_part;
4✔
650
        }
651

652
        $sec_sign = $this->seconds < 0 || $this->nanoseconds < 0 ? '-' : '';
15✔
653
        $sec = Math\abs($this->seconds);
15✔
654

655
        $containsHours = $this->hours !== 0;
15✔
656
        $containsMinutes = $this->minutes !== 0;
15✔
657
        $concatenatedSeconds = $sec_sign . (string) $sec . $decimal_part;
15✔
658
        $containsSeconds = $concatenatedSeconds !== '0';
15✔
659

660
        /** @var list<string> $output */
661
        $output = [];
15✔
662
        if ($containsHours) {
15✔
663
            $output[] = (string) $this->hours . ' hour(s)';
7✔
664
        }
665

666
        if ($containsMinutes || $containsHours && $containsSeconds) {
15✔
667
            $output[] = (string) $this->minutes . ' minute(s)';
8✔
668
        }
669

670
        if ($containsSeconds) {
15✔
671
            $output[] = $concatenatedSeconds . ' second(s)';
10✔
672
        }
673

674
        return [] === $output ? '0 second(s)' : Str\join($output, ', ');
15✔
675
    }
676

677
    /**
678
     * Returns a string representation of the time duration.
679
     *
680
     * @psalm-mutation-free
681
     */
682
    #[\Override]
683
    public function __toString(): string
684
    {
UNCOV
685
        return $this->toString();
×
686
    }
687

688
    /**
689
     * Returns data which can be serialized by json_encode().
690
     *
691
     * @return array{hours: int, minutes: int, seconds: int, nanoseconds: int}
692
     *
693
     * @psalm-mutation-free
694
     */
695
    #[\Override]
696
    public function jsonSerialize(): array
697
    {
698
        return [
1✔
699
            'hours' => $this->hours,
1✔
700
            'minutes' => $this->minutes,
1✔
701
            'seconds' => $this->seconds,
1✔
702
            'nanoseconds' => $this->nanoseconds,
1✔
703
        ];
1✔
704
    }
705
}
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