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

azjezz / psl / 22519606807

28 Feb 2026 11:11AM UTC coverage: 97.532% (-1.2%) from 98.733%
22519606807

push

github

web-flow
feat(network): rewrite networking stack with TLS, UDP, SOCKS5, CIDR, and IO utilities (#585)

860 of 937 new or added lines in 31 files covered. (91.78%)

15 existing lines in 6 files now uncovered.

7470 of 7659 relevant lines covered (97.53%)

42.83 hits per line

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

95.77
/src/Psl/DateTime/DateTime.php
1
<?php
2

3
declare(strict_types=1);
4

5
namespace Psl\DateTime;
6

7
use DateTimeImmutable;
8
use IntlCalendar;
9
use Override;
10
use Psl\Interoperability;
11
use Psl\Locale\Locale;
12

13
/**
14
 * @psalm-immutable
15
 *
16
 * @implements Interoperability\ToStdlib<DateTimeImmutable>
17
 * @implements Interoperability\FromStdlib<DateTimeImmutable>
18
 * @implements Interoperability\ToIntl<IntlCalendar>
19
 * @implements Interoperability\FromIntl<IntlCalendar>
20
 */
21
final readonly class DateTime implements
22
    DateTimeInterface,
23
    Interoperability\ToStdlib,
24
    Interoperability\FromStdlib,
25
    Interoperability\ToIntl,
26
    Interoperability\FromIntl
27
{
28
    use DateTimeConvenienceMethodsTrait;
29

30
    private Timezone $timezone;
31

32
    private Timestamp $timestamp;
33

34
    private int $year;
35

36
    /**
37
     * @var int<1, 12>
38
     */
39
    private int $month;
40

41
    /**
42
     * @var int<1, 31>
43
     */
44
    private int $day;
45

46
    /**
47
     * @var int<0, 23>
48
     */
49
    private int $hours;
50

51
    /**
52
     * @var int<0, 59>
53
     */
54
    private int $minutes;
55

56
    /**
57
     * @var int<0, 59>
58
     */
59
    private int $seconds;
60

61
    /**
62
     * @var int<0, 999999999>
63
     */
64
    private int $nanoseconds;
65

66
    /**
67
     * Constructs a new date-time instance with specified components and timezone.
68
     *
69
     * This constructor initializes a date-time object with the provided year, month, day, hour, minute,
70
     * second, and nanosecond components within the given timezone. It ensures that all components are within their
71
     * valid ranges: nanoseconds [0, 999,999,999], seconds [0, 59], minutes [0, 59], hours [0, 23], month [1, 12],
72
     * and day [1, 28-31] depending on the month and leap year status. The constructor validates these components and
73
     * assigns them to the instance if they are valid. If any component is out of its valid range, an
74
     * `Exception\InvalidDateTimeException` is thrown.
75
     *
76
     * @throws Exception\InvalidArgumentException If any of the date or time components are outside their valid ranges,
77
     *                                            indicating an invalid date-time configuration.
78
     *
79
     * @psalm-mutation-free
80
     */
81
    private function __construct(
82
        Timezone $timezone,
83
        Timestamp $timestamp,
84
        int $year,
85
        int $month,
86
        int $day,
87
        int $hours,
88
        int $minutes,
89
        int $seconds,
90
        int $nanoseconds,
91
    ) {
92
        if ($nanoseconds < 0 || $nanoseconds >= NANOSECONDS_PER_SECOND) {
46✔
UNCOV
93
            throw Exception\InvalidArgumentException::forNanoseconds($nanoseconds);
×
94
        }
95

96
        if ($seconds < 0 || $seconds >= 60) {
46✔
UNCOV
97
            throw Exception\InvalidArgumentException::forSeconds($seconds);
×
98
        }
99

100
        if ($minutes < 0 || $minutes >= 60) {
46✔
UNCOV
101
            throw Exception\InvalidArgumentException::forMinutes($minutes);
×
102
        }
103

104
        if ($hours < 0 || $hours >= 24) {
46✔
UNCOV
105
            throw Exception\InvalidArgumentException::forHours($hours);
×
106
        }
107

108
        if ($month < 1 || $month > 12) {
46✔
UNCOV
109
            throw Exception\InvalidArgumentException::forMonth($month);
×
110
        }
111

112
        if ($day < 1 || $day > 31 || $day > Month::from($month)->getDaysForYear($year)) {
46✔
UNCOV
113
            throw Exception\InvalidArgumentException::forDay($day, $month, $year);
×
114
        }
115

116
        $this->timestamp = $timestamp;
46✔
117
        $this->timezone = $timezone;
46✔
118
        $this->year = $year;
46✔
119
        $this->month = $month;
46✔
120
        $this->day = $day;
46✔
121
        $this->hours = $hours;
46✔
122
        $this->minutes = $minutes;
46✔
123
        $this->seconds = $seconds;
46✔
124
        $this->nanoseconds = $nanoseconds;
46✔
125
    }
126

127
    /**
128
     * Creates a new {@see DateTime} instance representing the current moment.
129
     *
130
     * This static method returns a {@see DateTime} object set to the current date and time. If a specific timezone is
131
     * provided, the returned {@see DateTime} will be adjusted to reflect the date and time in that timezone.
132
     *
133
     * @param null|Timezone $timezone Optional timezone. If null, uses the system's default timezone.
134
     *
135
     * @psalm-mutation-free
136
     */
137
    public static function now(null|Timezone $timezone = null): DateTime
138
    {
139
        return self::fromTimestamp(Timestamp::now(), $timezone);
4✔
140
    }
141

142
    /**
143
     * Creates a DateTime instance for a specific time on the current day within the specified timezone.
144
     *
145
     * This method facilitates the creation of a {@see DateTime} object representing a precise time on today's date. It is
146
     * particularly useful when you need to set a specific time of day for the current date in a given timezone. The
147
     * method combines the current date context with a specific time, offering a convenient way to specify times such
148
     * as "today at 14:00" in code.
149
     *
150
     * The time components (hours, minutes, seconds, nanoseconds) must be within their valid ranges. The method
151
     * enforces these constraints and throws an {@see Exception\InvalidArgumentException} if any component is out of bounds.
152
     *
153
     * @param int<0, 23> $hours The hour component of the time, ranging from 0 to 23.
154
     * @param int<0, 59> $minutes The minute component of the time, ranging from 0 to 59.
155
     * @param int<0, 59> $seconds The second component of the time, defaulting to 0, and ranging from 0 to 59.
156
     * @param int<0, 999999999> $nanoseconds The nanosecond component of the time, defaulting to 0, and ranging from 0 to 999,999,999.
157
     *
158
     * @throws Exception\UnexpectedValueException If any of the provided time components do not align with calendar expectations.
159
     *
160
     * @psalm-mutation-free
161
     */
162
    public static function todayAt(
163
        int $hours,
164
        int $minutes,
165
        int $seconds = 0,
166
        int $nanoseconds = 0,
167
        null|Timezone $timezone = null,
168
    ): DateTime {
169
        return self::now($timezone)->withTime($hours, $minutes, $seconds, $nanoseconds);
3✔
170
    }
171

172
    /**
173
     * Creates a {@see DateTime} instance from individual date and time components.
174
     *
175
     * This method constructs a DateTime object using the specified year, month, day, hour, minute, second,
176
     * and nanosecond components within a given timezone. It validates each component against the Gregorian calendar
177
     * to ensure the date and time are possible. For example, it checks for the correct range of months (1-12),
178
     * days in a month (considering leap years), hours (0-23), minutes (0-59), and seconds (0-59).
179
     *
180
     * Note: In cases where the specified time occurs twice (such as during the end of daylight saving time), the earlier occurrence
181
     * is returned. To obtain the later occurrence, you can adjust the returned instance using `->plusHours(1)`.
182
     *
183
     * @param Month|int<1, 12> $month
184
     * @param int<1, 31> $day
185
     * @param int<0, 23> $hours
186
     * @param int<0, 59> $minutes
187
     * @param int<0, 59> $seconds
188
     * @param int<0, 999999999> $nanoseconds
189
     *
190
     * @throws Exception\UnexpectedValueException If any of the provided date or time components do not align with calendar expectations.
191
     *
192
     * @pure
193
     */
194
    public static function fromParts(
195
        Timezone $timezone,
196
        int $year,
197
        Month|int $month,
198
        int $day,
199
        int $hours = 0,
200
        int $minutes = 0,
201
        int $seconds = 0,
202
        int $nanoseconds = 0,
203
    ): self {
204
        if ($month instanceof Month) {
47✔
205
            $month = $month->value;
30✔
206
        }
207

208
        $calendar = Internal\create_intl_calendar_from_date_time(
47✔
209
            $timezone,
47✔
210
            $year,
47✔
211
            $month,
47✔
212
            $day,
47✔
213
            $hours,
47✔
214
            $minutes,
47✔
215
            $seconds,
47✔
216
        );
47✔
217

218
        if ($seconds !== $calendar->get(IntlCalendar::FIELD_SECOND)) {
47✔
219
            throw Exception\UnexpectedValueException::forSeconds($seconds, $calendar->get(IntlCalendar::FIELD_SECOND));
1✔
220
        }
221

222
        if ($minutes !== $calendar->get(IntlCalendar::FIELD_MINUTE)) {
46✔
223
            throw Exception\UnexpectedValueException::forMinutes($minutes, $calendar->get(IntlCalendar::FIELD_MINUTE));
1✔
224
        }
225

226
        if ($hours !== $calendar->get(IntlCalendar::FIELD_HOUR_OF_DAY)) {
45✔
227
            throw Exception\UnexpectedValueException::forHours($hours, $calendar->get(IntlCalendar::FIELD_HOUR_OF_DAY));
1✔
228
        }
229

230
        if ($day !== $calendar->get(IntlCalendar::FIELD_DAY_OF_MONTH)) {
44✔
231
            throw Exception\UnexpectedValueException::forDay($day, $calendar->get(IntlCalendar::FIELD_DAY_OF_MONTH));
1✔
232
        }
233

234
        if ($month !== ($calendar->get(IntlCalendar::FIELD_MONTH) + 1)) {
43✔
235
            throw Exception\UnexpectedValueException::forMonth($month, $calendar->get(IntlCalendar::FIELD_MONTH) + 1);
1✔
236
        }
237

238
        if ($year !== $calendar->get(IntlCalendar::FIELD_YEAR)) {
42✔
239
            throw Exception\UnexpectedValueException::forYear($year, $calendar->get(IntlCalendar::FIELD_YEAR));
1✔
240
        }
241

242
        $timestamp_in_seconds = (int) ($calendar->getTime() / (float) MILLISECONDS_PER_SECOND);
41✔
243
        $timestamp = Timestamp::fromParts($timestamp_in_seconds, $nanoseconds);
41✔
244

245
        return new self($timezone, $timestamp, $year, $month, $day, $hours, $minutes, $seconds, $nanoseconds);
41✔
246
    }
247

248
    /**
249
     * Creates a {@see DateTime} instance from a timestamp, representing the same point in time.
250
     *
251
     * This method converts a {@see Timestamp} into a {@see DateTime} instance calculated for the specified timezone.
252
     *
253
     * @param null|Timezone $timezone Optional timezone. If null, uses the system's default timezone.
254
     *
255
     * @see Timezone::default()
256
     *
257
     * @psalm-mutation-free
258
     */
259
    #[Override]
260
    public static function fromTimestamp(Timestamp $timestamp, null|Timezone $timezone = null): static
261
    {
262
        $timezone ??= Timezone::default();
16✔
263

264
        /** @var IntlCalendar $calendar */
265
        $calendar = IntlCalendar::createInstance(Internal\to_intl_timezone($timezone));
16✔
266

267
        $calendar->setTime($timestamp->getSeconds() * MILLISECONDS_PER_SECOND);
16✔
268

269
        $year = $calendar->get(IntlCalendar::FIELD_YEAR);
16✔
270
        $month = $calendar->get(IntlCalendar::FIELD_MONTH) + 1;
16✔
271
        $day = $calendar->get(IntlCalendar::FIELD_DAY_OF_MONTH);
16✔
272
        $hour = $calendar->get(IntlCalendar::FIELD_HOUR_OF_DAY);
16✔
273
        $minute = $calendar->get(IntlCalendar::FIELD_MINUTE);
16✔
274
        $second = $calendar->get(IntlCalendar::FIELD_SECOND);
16✔
275
        $nanoseconds = $timestamp->getNanoseconds();
16✔
276

277
        return new static($timezone, $timestamp, $year, $month, $day, $hour, $minute, $second, $nanoseconds);
16✔
278
    }
279

280
    /**
281
     * Parses a date and time string into an instance of {@see Timestamp} using a specific format pattern, with optional customization for timezone and locale.
282
     *
283
     * This method is specifically designed for cases where a custom format pattern is used to parse the input string.
284
     *
285
     * It allows for precise control over the parsing process by specifying the exact format pattern that matches the input string.
286
     *
287
     * Additionally, the method supports specifying a timezone and locale for parsing, enabling accurate interpretation of locale-specific formats.
288
     *
289
     * Example usage:
290
     *
291
     * ```php
292
     * $raw_string = '2023-03-15 12:00:00';
293
     * $parsed_datetime = DateTime\DateTime::parse($raw_string, 'yyyy-MM-dd HH:mm:ss', DateTime\Timezone::Utc, Locale\Locale::English);
294
     * ```
295
     *
296
     * @param string $raw_string The date and time string to parse.
297
     * @param null|FormatPattern|string $pattern The custom format pattern for parsing the date and time. If null, uses a default pattern.
298
     * @param null|Timezone $timezone Optional timezone for parsing. If null, uses the system's default timezone.
299
     * @param null|Locale $locale Optional locale for parsing. If null, uses the system's default locale.
300
     *
301
     * @throws Exception\RuntimeException If the parsing process fails.
302
     *
303
     * @return static Returns an instance of {@see Timestamp} representing the parsed date and time.
304
     *
305
     * @see https://unicode-org.github.io/icu/userguide/format_parse/datetime/#datetime-format-syntax
306
     * @see TemporalInterface::format()
307
     *
308
     * @psalm-mutation-free
309
     */
310
    public static function parse(
311
        string $raw_string,
312
        null|FormatPattern|string $pattern = null,
313
        null|Timezone $timezone = null,
314
        null|Locale $locale = null,
315
    ): static {
316
        $timezone ??= Timezone::default();
2✔
317

318
        return self::fromTimestamp(Timestamp::parse($raw_string, $pattern, $timezone, $locale), $timezone);
2✔
319
    }
320

321
    /**
322
     * Creates an instance of {@see DateTime} from a date and time string, formatted according to specified styles for date and time,
323
     * with optional customization for timezone and locale.
324
     *
325
     * This method provides a more abstracted approach to parsing, allowing users  to specify styles rather than a custom pattern.
326
     *
327
     * This is particularly useful for parsing strings that follow common date and time formats.
328
     *
329
     * Additionally, the timezone and locale parameters enable accurate parsing of strings in locale-specific formats.
330
     *
331
     * Example usage:
332
     *
333
     * ```php
334
     * $raw_string = "March 15, 2023, 12:00 PM";
335
     *
336
     * $datetime = DateTime\DateTime::fromString($raw_string, FormatDateStyle::Long, FormatTimeStyle::Short, DateTime\Timezone::Utc, Locale\Locale::English);
337
     * ```
338
     *
339
     * @param string $raw_string The date and time string to parse.
340
     * @param null|DateStyle $date_style The style for the date portion of the string. If null, a default style is used.
341
     * @param null|TimeStyle $time_style The style for the time portion of the string. If null, a default style is used.
342
     * @param null|Timezone $timezone Optional timezone for parsing. If null, uses the system's default timezone.
343
     * @param null|Locale $locale Optional locale for parsing. If null, uses the system's default locale.
344
     *
345
     * @throws Exception\RuntimeException If the parsing process fails.
346
     *
347
     * @return static Returns an instance of {@see DateTime} representing the parsed date and time.
348
     *
349
     * @see DateTimeInterface::toString()
350
     *
351
     * @psalm-mutation-free
352
     */
353
    public static function fromString(
354
        string $raw_string,
355
        null|DateStyle $date_style = null,
356
        null|TimeStyle $time_style = null,
357
        null|Timezone $timezone = null,
358
        null|Locale $locale = null,
359
    ): static {
360
        $timezone ??= Timezone::default();
1✔
361

362
        return self::fromTimestamp(
1✔
363
            Timestamp::fromString($raw_string, $date_style, $time_style, $timezone, $locale),
1✔
364
            $timezone,
1✔
365
        );
1✔
366
    }
367

368
    /**
369
     * Returns the timestamp representation of this date time object.
370
     *
371
     * @psalm-mutation-free
372
     */
373
    #[Override]
374
    public function getTimestamp(): Timestamp
375
    {
376
        return $this->timestamp;
18✔
377
    }
378

379
    /**
380
     * Retrieves the year as an integer, following ISO-8601 conventions for numbering.
381
     *
382
     * This method returns the year part of the date. For years in the Anno Domini (AD) era, the returned value matches
383
     * the Gregorian calendar year directly (e.g., 1 for AD 1, 2021 for AD 2021, etc.). For years before AD 1, the method
384
     * adheres to the ISO-8601 standard, which does not use a year zero: 1 BC is represented as 0, 2 BC as -1, 3 BC as -2,
385
     * and so forth. This ISO-8601 numbering facilitates straightforward mathematical operations on years across the AD/BC
386
     * divide but may require conversion for user-friendly display or when interfacing with systems that use the traditional
387
     * AD/BC notation.
388
     *
389
     * @return int The year, formatted according to ISO-8601 standards, where 1 AD is 1, 1 BC is 0, 2 BC is -1, etc.
390
     *
391
     * @psalm-mutation-free
392
     */
393
    #[Override]
394
    public function getYear(): int
395
    {
396
        return $this->year;
22✔
397
    }
398

399
    /**
400
     * Returns the month.
401
     *
402
     * @return int<1, 12>
403
     *
404
     * @psalm-mutation-free
405
     */
406
    #[Override]
407
    public function getMonth(): int
408
    {
409
        return $this->month;
19✔
410
    }
411

412
    /**
413
     * Returns the day.
414
     *
415
     * @return int<1, 31>
416
     *
417
     * @psalm-mutation-free
418
     */
419
    #[Override]
420
    public function getDay(): int
421
    {
422
        return $this->day;
19✔
423
    }
424

425
    /**
426
     * Returns the hours.
427
     *
428
     * @return int<0, 23>
429
     *
430
     * @psalm-mutation-free
431
     */
432
    #[Override]
433
    public function getHours(): int
434
    {
435
        return $this->hours;
26✔
436
    }
437

438
    /**
439
     * Returns the minutes.
440
     *
441
     * @return int<0, 59>
442
     *
443
     * @psalm-mutation-free
444
     */
445
    #[Override]
446
    public function getMinutes(): int
447
    {
448
        return $this->minutes;
17✔
449
    }
450

451
    /**
452
     * Returns the seconds.
453
     *
454
     * @return int<0, 59>
455
     *
456
     * @psalm-mutation-free
457
     */
458
    #[Override]
459
    public function getSeconds(): int
460
    {
461
        return $this->seconds;
17✔
462
    }
463

464
    /**
465
     * Returns the nanoseconds.
466
     *
467
     * @return int<0, 999999999>
468
     *
469
     * @psalm-mutation-free
470
     */
471
    #[Override]
472
    public function getNanoseconds(): int
473
    {
474
        return $this->nanoseconds;
15✔
475
    }
476

477
    /**
478
     * Gets the timezone associated with the date and time.
479
     *
480
     * @psalm-mutation-free
481
     */
482
    #[Override]
483
    public function getTimezone(): Timezone
484
    {
485
        return $this->timezone;
28✔
486
    }
487

488
    /**
489
     * Returns a new instance with the specified date.
490
     *
491
     * @param Month|int<1, 12> $month
492
     * @param int<1, 31> $day
493
     *
494
     * @throws Exception\UnexpectedValueException If any of the provided date components do not align with calendar expectations.
495
     *
496
     * @psalm-mutation-free
497
     */
498
    #[Override]
499
    public function withDate(int $year, Month|int $month, int $day): static
500
    {
501
        return static::fromParts(
8✔
502
            $this->getTimezone(),
8✔
503
            $year,
8✔
504
            $month,
8✔
505
            $day,
8✔
506
            $this->getHours(),
8✔
507
            $this->getMinutes(),
8✔
508
            $this->getSeconds(),
8✔
509
            $this->getNanoseconds(),
8✔
510
        );
8✔
511
    }
512

513
    /**
514
     * Returns a new instance with the specified time.
515
     *
516
     * @param int<0, 23> $hours
517
     * @param int<0, 59> $minutes
518
     * @param int<0, 59> $seconds
519
     * @param int<0, 999999999> $nanoseconds
520
     *
521
     * @throws Exception\UnexpectedValueException If any of the provided time components do not align with calendar expectations.
522
     *
523
     * @psalm-mutation-free
524
     */
525
    #[Override]
526
    public function withTime(int $hours, int $minutes, int $seconds = 0, int $nanoseconds = 0): static
527
    {
528
        return static::fromParts(
4✔
529
            $this->getTimezone(),
4✔
530
            $this->getYear(),
4✔
531
            $this->getMonth(),
4✔
532
            $this->getDay(),
4✔
533
            $hours,
4✔
534
            $minutes,
4✔
535
            $seconds,
4✔
536
            $nanoseconds,
4✔
537
        );
4✔
538
    }
539

540
    /**
541
     * Creates a {@see DateTime} instance from a PHP {@see DateTimeImmutable}.
542
     *
543
     * @param DateTimeImmutable $value
544
     *
545
     * @psalm-mutation-free
546
     */
547
    #[Override]
548
    public static function fromStdlib(mixed $value): static
549
    {
550
        /** @var \DateTimeZone $tz */
551
        $tz = $value->getTimezone();
2✔
552
        $timezone = Timezone::from($tz->getName());
2✔
553
        $seconds = $value->getTimestamp();
2✔
554
        $microseconds = (int) $value->format('u');
2✔
555
        $nanoseconds = $microseconds * NANOSECONDS_PER_MICROSECOND;
2✔
556

557
        return self::fromTimestamp(Timestamp::fromParts($seconds, $nanoseconds), $timezone);
2✔
558
    }
559

560
    /**
561
     * Converts this {@see DateTime} to a PHP {@see DateTimeImmutable}.
562
     *
563
     * Note: nanosecond precision is truncated to microseconds.
564
     *
565
     * @return DateTimeImmutable
566
     *
567
     * @psalm-mutation-free
568
     */
569
    #[Override]
570
    public function toStdlib(): mixed
571
    {
572
        $microseconds = (int) ($this->nanoseconds / NANOSECONDS_PER_MICROSECOND);
2✔
573
        $formatted = \sprintf(
2✔
574
            '%04d-%02d-%02d %02d:%02d:%02d.%06d',
2✔
575
            $this->year,
2✔
576
            $this->month,
2✔
577
            $this->day,
2✔
578
            $this->hours,
2✔
579
            $this->minutes,
2✔
580
            $this->seconds,
2✔
581
            $microseconds,
2✔
582
        );
2✔
583

584
        return new DateTimeImmutable($formatted, new \DateTimeZone($this->timezone->value));
2✔
585
    }
586

587
    /**
588
     * Creates a {@see DateTime} instance from an {@see IntlCalendar}.
589
     *
590
     * @param IntlCalendar $value
591
     *
592
     * @psalm-mutation-free
593
     */
594
    #[Override]
595
    public static function fromIntl(mixed $value): static
596
    {
597
        /** @var \IntlTimeZone $intl_tz */
598
        $intl_tz = $value->getTimeZone();
2✔
599
        /** @var string $timezone_id */
600
        $timezone_id = $intl_tz->getID();
2✔
601
        $timezone = Timezone::from($timezone_id);
2✔
602
        $millis = $value->getTime();
2✔
603
        $seconds = (int) ($millis / MILLISECONDS_PER_SECOND);
2✔
604
        $remaining_millis = $millis % MILLISECONDS_PER_SECOND;
2✔
605
        $nanoseconds = (int) ($remaining_millis * NANOSECONDS_PER_MILLISECOND);
2✔
606

607
        return self::fromTimestamp(Timestamp::fromParts($seconds, $nanoseconds), $timezone);
2✔
608
    }
609

610
    /**
611
     * Converts this {@see DateTime} to an {@see IntlCalendar}.
612
     *
613
     * Note: nanosecond precision is truncated to milliseconds.
614
     *
615
     * @return IntlCalendar
616
     *
617
     * @psalm-mutation-free
618
     */
619
    #[Override]
620
    public function toIntl(): mixed
621
    {
622
        return Internal\create_intl_calendar_from_date_time(
2✔
623
            $this->timezone,
2✔
624
            $this->year,
2✔
625
            $this->month,
2✔
626
            $this->day,
2✔
627
            $this->hours,
2✔
628
            $this->minutes,
2✔
629
            $this->seconds,
2✔
630
        );
2✔
631
    }
632

633
    #[Override]
634
    public function jsonSerialize(): array
635
    {
636
        return [
1✔
637
            'timezone' => $this->timezone,
1✔
638
            'timestamp' => $this->timestamp,
1✔
639
            'year' => $this->year,
1✔
640
            'month' => $this->month,
1✔
641
            'day' => $this->day,
1✔
642
            'hours' => $this->hours,
1✔
643
            'minutes' => $this->minutes,
1✔
644
            'seconds' => $this->seconds,
1✔
645
            'nanoseconds' => $this->nanoseconds,
1✔
646
        ];
1✔
647
    }
648
}
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