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

johnykvsky / dummygenerator / 22286702151

22 Feb 2026 10:27PM UTC coverage: 99.419% (+0.6%) from 98.778%
22286702151

Pull #38

github

web-flow
Merge 556021dd2 into 4286d41f2
Pull Request #38: Version 0.2.0

309 of 310 new or added lines in 37 files covered. (99.68%)

1 existing line in 1 file now uncovered.

1027 of 1033 relevant lines covered (99.42%)

65.94 hits per line

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

97.01
/src/Core/DateTime.php
1
<?php
2

3
declare(strict_types = 1);
4

5
namespace DummyGenerator\Core;
6

7
use DateInterval;
8
use DateTimeImmutable;
9
use DateTimeInterface;
10
use DateTimeZone;
11
use DummyGenerator\Clock\SystemClockInterface;
12
use DummyGenerator\Definitions\Extension\DateTimeExtensionInterface;
13
use DummyGenerator\Definitions\Extension\Exception\ExtensionArgumentException;
14
use DummyGenerator\Definitions\Randomizer\RandomizerInterface;
15

16
class DateTime implements DateTimeExtensionInterface
17
{
18
    public function __construct(
19
        protected RandomizerInterface $randomizer,
20
        protected SystemClockInterface $clock
21
    ) {
22
    }
52✔
23

24
    /** @var string[] */
25
    protected array $centuries = ['I', 'II', 'III', 'IV', 'V', 'VI', 'VII', 'VIII', 'IX', 'X', 'XI', 'XII', 'XIII', 'XIV', 'XV', 'XVI', 'XVII', 'XVIII', 'XIX', 'XX', 'XXI'];
26

27
    public function dateTime(DateTimeInterface|string $until = 'now', ?string $timezone = null): \DateTimeInterface
28
    {
29
        return $this->setTimezone(
16✔
30
            $this->getTimestampDateTime($this->unixTime($until)),
16✔
31
            $timezone,
16✔
32
        );
16✔
33
    }
34

35
    public function dateTimeAD(DateTimeInterface|string $until = 'now', ?string $timezone = null): \DateTimeInterface
36
    {
37
        $min = (PHP_INT_SIZE > 4) ? -62135597361 : -PHP_INT_MAX;
1✔
38

39
        return $this->setTimezone(
1✔
40
            $this->getTimestampDateTime($this->randomizer->getInt($min, $this->getTimestamp($until))),
1✔
41
            $timezone,
1✔
42
        );
1✔
43
    }
44

45
    public function dateTimeBetween(DateTimeInterface|string $from = '-30 years', DateTimeInterface|string $until = 'now', ?string $timezone = null): \DateTimeInterface
46
    {
47
        $start = $this->getTimestamp($from);
16✔
48
        $end = $this->getTimestamp($until);
16✔
49

50
        if ($start > $end) {
16✔
51
            throw new ExtensionArgumentException('"$from" must be anterior to "$until".');
2✔
52
        }
53

54
        $timestamp = $this->randomizer->getInt($start, $end);
14✔
55

56
        return $this->setTimezone(
14✔
57
            $this->getTimestampDateTime($timestamp),
14✔
58
            $timezone,
14✔
59
        );
14✔
60
    }
61

62
    public function dateTimeInInterval(
63
        DateTimeInterface|string $from = '-30 years',
64
        DateInterval|string $interval = '+5 days',
65
        ?string $timezone = null
66
    ): \DateTimeInterface {
67
        $intervalObject = $interval instanceof DateInterval ? $interval : DateInterval::createFromDateString($interval);
2✔
68
        $datetime = $from instanceof \DateTimeInterface ? $from : new \DateTimeImmutable((string) $from);
2✔
69

70
        // @phpstan-ignore-next-line
71
        $other = $datetime->add($intervalObject);
2✔
72

73
        $begin = min($datetime, $other);
2✔
74
        $end = $datetime === $begin ? $other : $datetime;
2✔
75

76
        return $this->dateTimeBetween($begin, $end, $timezone);
2✔
77
    }
78

79
    public function dateTimeThisWeek(DateTimeInterface|string $until = 'sunday this week', ?string $timezone = null): \DateTimeInterface
80
    {
81
        $from = $this->clock->now();
2✔
82

83
        if ($timezone !== null) {
2✔
84
            $from = $from->setTimezone(new DateTimeZone($timezone));
2✔
85
        }
86

87
        if ($from->format('w') !== '1') {
2✔
88
            $from = $from->modify('last monday');
1✔
89
        }
90

91
        $from = $from->setTime(0, 0, 0);
2✔
92

93
        return $this->dateTimeBetween($from, $until, $timezone);
2✔
94
    }
95

96
    public function dateTimeThisMonth(DateTimeInterface|string $until = 'last day of this month', ?string $timezone = null): \DateTimeInterface
97
    {
98
        return $this->dateTimeBetween('first day of this month', $until, $timezone);
1✔
99
    }
100

101
    public function dateTimeThisYear(DateTimeInterface|string $until = 'last day of december', ?string $timezone = null): \DateTimeInterface
102
    {
103
        return $this->dateTimeBetween('first day of january', $until, $timezone);
2✔
104
    }
105

106
    public function dateTimeThisDecade(DateTimeInterface|string $until = 'now', ?string $timezone = null): \DateTimeInterface
107
    {
108
        $year = floor(date('Y') / 10) * 10;
1✔
109

110
        return $this->dateTimeBetween("first day of january $year", $until, $timezone);
1✔
111
    }
112

113
    public function dateTimeThisCentury(DateTimeInterface|string $until = 'now', ?string $timezone = null): \DateTimeInterface
114
    {
115
        $year = floor(date('Y') / 100) * 100;
1✔
116

117
        return $this->dateTimeBetween("first day of january $year", $until, $timezone);
1✔
118
    }
119

120
    public function date(string $format = 'Y-m-d', DateTimeInterface|string $until = 'now'): string
121
    {
122
        return $this->dateTime($until)->format($format);
11✔
123
    }
124

125
    public function time(string $format = 'H:i:s', DateTimeInterface|string $until = 'now'): string
126
    {
127
        return $this->date($format, $until);
1✔
128
    }
129

130
    public function unixTime(DateTimeInterface|string $until = 'now'): int
131
    {
132
        return $this->randomizer->getInt(0, $this->getTimestamp($until));
17✔
133
    }
134

135
    public function iso8601(DateTimeInterface|string $until = 'now'): string
136
    {
137
        return $this->date(DateTimeInterface::ATOM, $until);
1✔
138
    }
139

140
    public function amPm(DateTimeInterface|string $until = 'now'): string
141
    {
142
        return $this->date('a', $until);
1✔
143
    }
144

145
    public function dayOfMonth(DateTimeInterface|string $until = 'now'): string
146
    {
147
        return $this->date('d', $until);
2✔
148
    }
149

150
    public function dayOfWeek(DateTimeInterface|string $until = 'now'): string
151
    {
152
        return $this->date('l', $until);
1✔
153
    }
154

155
    public function month(DateTimeInterface|string $until = 'now'): string
156
    {
157
        return $this->date('m', $until);
2✔
158
    }
159

160
    public function monthName(DateTimeInterface|string $until = 'now'): string
161
    {
162
        return $this->date('F', $until);
1✔
163
    }
164

165
    public function year(DateTimeInterface|string $until = 'now'): string
166
    {
167
        return $this->date('Y', $until);
3✔
168
    }
169

170
    public function century(): string
171
    {
172
        return $this->randomizer->randomElement($this->centuries);
1✔
173
    }
174

175
    public function timezone(): string
176
    {
177
        return $this->randomizer->randomElement(\DateTimeZone::listIdentifiers());
1✔
178
    }
179

180
    /**
181
     * Get the POSIX-timestamp of a DateTime or string (can be epoch as "1733785884").
182
     */
183
    protected function getTimestamp(\DateTimeInterface|string $until = 'now'): int
184
    {
185
        if (is_numeric($until)) {
33✔
186
            return (int) $until;
1✔
187
        }
188

189
        if ($until instanceof \DateTimeInterface) {
33✔
190
            return $until->getTimestamp();
22✔
191
        }
192

193
        return $this->getDateTimeFromString($until)->getTimestamp();
16✔
194
    }
195

196
    /**
197
     * Get a DateTimeImmutable created based on a POSIX-timestamp.
198
     *
199
     * @param int $timestamp the UNIX / POSIX-compatible timestamp
200
     * @throws \DateMalformedStringException
201
     */
202
    protected function getTimestampDateTime(int $timestamp): \DateTimeInterface
203
    {
204
        return new \DateTimeImmutable('@' . $timestamp);
30✔
205
    }
206

207
    protected function resolveTimezone(?string $timezone): string
208
    {
209
        if ($timezone === null) {
30✔
210
            return date_default_timezone_get();
18✔
211
        }
212

213
        $timezones = \DateTimeZone::listIdentifiers();
12✔
214
        if (in_array($timezone, $timezones, true)) {
12✔
215
            return $timezone;
11✔
216
        }
217

218
        throw new ExtensionArgumentException('"$timezone" is not a valid timezone.');
1✔
219
    }
220

221
    /**
222
     * Internal method to set the timezone on a DateTime object.
223
     */
224
    protected function setTimezone(\DateTimeInterface $dateTime, ?string $timezone): \DateTimeInterface
225
    {
226
        $timezone = $this->resolveTimezone($timezone);
30✔
227

228
        // @phpstan-ignore-next-line
229
        return $dateTime->setTimezone(new \DateTimeZone($timezone));
29✔
230
    }
231

232
    protected function getDateTimeFromString(string $dateString): DateTimeInterface
233
    {
234
        try {
235
            return new DateTimeImmutable($dateString);
16✔
236
        } catch (\Throwable $e) {
×
UNCOV
237
            throw new ExtensionArgumentException('Invalid datetime string given.', $e->getCode(), $e);
×
238
        }
239
    }
240
}
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