Skip to content

Commit 9beb382

Browse files
authored
Add method createDateTimeFromFormat (#17)
1 parent f579c69 commit 9beb382

5 files changed

Lines changed: 170 additions & 0 deletions

File tree

src/DateTimeHelper.php

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212

1313
namespace Fresh\DateTime;
1414

15+
use Fresh\DateTime\Exception\InvalidArgumentException;
1516
use Psr\Clock\ClockInterface;
1617

1718
/**
@@ -22,6 +23,7 @@
2223
class DateTimeHelper implements ClockInterface, DateTimeHelperInterface
2324
{
2425
private const string INTERNAL_DATE_FORMAT = 'Y-m-d';
26+
private const string INTERNAL_DATETIME_FORMAT = 'Y-m-d H:i:s';
2527

2628
/** @var array<string, \DateTimeInterface[]> */
2729
private array $datesCache = [];
@@ -138,6 +140,42 @@ public function getDatesFromDateRangeAsArrayOfStrings(DateRangeInterface $dateRa
138140
return $datesAsStrings;
139141
}
140142

143+
/**
144+
* {@inheritdoc}
145+
*/
146+
public function createDateTimeFromFormat(string $dateTimeAsString, string $dateFormat = self::INTERNAL_DATETIME_FORMAT, ?\DateTimeZone $timeZone = null): \DateTime
147+
{
148+
if ($timeZone instanceof \DateTimeZone) {
149+
$result = \DateTime::createFromFormat($dateFormat, $dateTimeAsString, $timeZone);
150+
} else {
151+
$result = \DateTime::createFromFormat($dateFormat, $dateTimeAsString, $this->createDateTimeZoneUtc());
152+
}
153+
154+
if (!$result instanceof \DateTime) {
155+
throw new InvalidArgumentException(\sprintf('Could not create a \DateTime object from string "%s" from format "%s".', $dateTimeAsString, $dateFormat));
156+
}
157+
158+
return $result;
159+
}
160+
161+
/**
162+
* {@inheritdoc}
163+
*/
164+
public function createDateTimeImmutableFromFormat(string $dateTimeAsString, string $dateFormat = self::INTERNAL_DATETIME_FORMAT, ?\DateTimeZone $timeZone = null): \DateTimeImmutable
165+
{
166+
if ($timeZone instanceof \DateTimeZone) {
167+
$result = \DateTimeImmutable::createFromFormat($dateFormat, $dateTimeAsString, $timeZone);
168+
} else {
169+
$result = \DateTimeImmutable::createFromFormat($dateFormat, $dateTimeAsString, $this->createDateTimeZoneUtc());
170+
}
171+
172+
if (!$result instanceof \DateTimeImmutable) {
173+
throw new InvalidArgumentException(\sprintf('Could not create a \DateTimeImmutable object from string "%s" from format "%s".', $dateTimeAsString, $dateFormat));
174+
}
175+
176+
return $result;
177+
}
178+
141179
/**
142180
* @param DateRangeInterface $dateRange
143181
*

src/DateTimeHelperInterface.php

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212

1313
namespace Fresh\DateTime;
1414

15+
use Fresh\DateTime\Exception\InvalidArgumentException;
1516
use Fresh\DateTime\Exception\UnexpectedValueException;
1617

1718
/**
@@ -79,4 +80,26 @@ public function getDatesFromDateRangeAsArrayOfObjects(DateRangeInterface $dateRa
7980
* @return string[]
8081
*/
8182
public function getDatesFromDateRangeAsArrayOfStrings(DateRangeInterface $dateRange): array;
83+
84+
/**
85+
* @param string $dateTimeAsString
86+
* @param string $dateFormat
87+
* @param \DateTimeZone|null $timeZone
88+
*
89+
* @throws InvalidArgumentException
90+
*
91+
* @return \DateTime
92+
*/
93+
public function createDateTimeFromFormat(string $dateTimeAsString, string $dateFormat, ?\DateTimeZone $timeZone = null): \DateTime;
94+
95+
/**
96+
* @param string $dateTimeAsString
97+
* @param string $dateFormat
98+
* @param \DateTimeZone|null $timeZone
99+
*
100+
* @throws InvalidArgumentException
101+
*
102+
* @return \DateTimeImmutable
103+
*/
104+
public function createDateTimeImmutableFromFormat(string $dateTimeAsString, string $dateFormat, ?\DateTimeZone $timeZone = null): \DateTimeImmutable;
82105
}
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
<?php
2+
/*
3+
* This file is part of the DateTime library.
4+
*
5+
* (c) Artem Henvald <genvaldartem@gmail.com>
6+
*
7+
* For the full copyright and license information, please view the LICENSE
8+
* file that was distributed with this source code.
9+
*/
10+
11+
declare(strict_types=1);
12+
13+
namespace Fresh\DateTime\Exception;
14+
15+
/**
16+
* InvalidArgumentException.
17+
*
18+
* @author Artem Henvald <genvaldartem@gmail.com>
19+
*/
20+
class InvalidArgumentException extends \InvalidArgumentException implements ExceptionInterface
21+
{
22+
}

tests/DateTimeHelperTest.php

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
use Fresh\DateTime\DateRangeInterface;
1616
use Fresh\DateTime\DateTimeHelper;
1717
use Fresh\DateTime\DateTimeHelperInterface;
18+
use Fresh\DateTime\Exception\InvalidArgumentException;
1819
use PHPUnit\Framework\Attributes\DataProvider;
1920
use PHPUnit\Framework\Attributes\Test;
2021
use PHPUnit\Framework\MockObject\MockObject;
@@ -230,4 +231,56 @@ public function datesCache(): void
230231
$this->assertSame($expectedDates, $dates1);
231232
$this->assertSame($expectedDates, $dates2);
232233
}
234+
235+
#[Test]
236+
public function createDateTimeFromFormatWithDefaultTimezone(): void
237+
{
238+
$dateTime = $this->dateTimeHelper->createDateTimeFromFormat(dateTimeAsString: '2000-01-01 00:00:00');
239+
$this->assertInstanceOf(\DateTime::class, $dateTime);
240+
$this->assertSame('UTC', $dateTime->getTimezone()->getName());
241+
}
242+
243+
#[Test]
244+
public function createDateTimeFromFormatWithCustomTimezone(): void
245+
{
246+
$dateTime = $this->dateTimeHelper->createDateTimeFromFormat(dateTimeAsString: '2000-01-01 00:00:00', timeZone: new \DateTimeZone('Europe/Berlin'));
247+
$this->assertInstanceOf(\DateTime::class, $dateTime);
248+
$this->assertSame('Europe/Berlin', $dateTime->getTimezone()->getName());
249+
}
250+
251+
#[Test]
252+
public function createDateTimeFromFormatWithException(): void
253+
{
254+
$this->expectException(InvalidArgumentException::class);
255+
$this->expectExceptionMessage('Could not create a \DateTime object from string "fake" from format "Y-m-d H:i:s".');
256+
257+
258+
$this->dateTimeHelper->createDateTimeFromFormat(dateTimeAsString: 'fake');
259+
}
260+
261+
#[Test]
262+
public function createDateTimeImmutableFromFormatWithDefaultTimezone(): void
263+
{
264+
$dateTime = $this->dateTimeHelper->createDateTimeImmutableFromFormat(dateTimeAsString: '2000-01-01 00:00:00');
265+
$this->assertInstanceOf(\DateTimeImmutable::class, $dateTime);
266+
$this->assertSame('UTC', $dateTime->getTimezone()->getName());
267+
}
268+
269+
#[Test]
270+
public function createDateTimeImmutableFromFormatWithCustomTimezone(): void
271+
{
272+
$dateTime = $this->dateTimeHelper->createDateTimeImmutableFromFormat(dateTimeAsString: '2000-01-01 00:00:00', timeZone: new \DateTimeZone('Europe/Berlin'));
273+
$this->assertInstanceOf(\DateTimeImmutable::class, $dateTime);
274+
$this->assertSame('Europe/Berlin', $dateTime->getTimezone()->getName());
275+
}
276+
277+
#[Test]
278+
public function createDateTimeImmutableFromFormatWithException(): void
279+
{
280+
$this->expectException(InvalidArgumentException::class);
281+
$this->expectExceptionMessage('Could not create a \DateTimeImmutable object from string "fake" from format "Y-m-d H:i:s".');
282+
283+
284+
$this->dateTimeHelper->createDateTimeImmutableFromFormat(dateTimeAsString: 'fake');
285+
}
233286
}
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
<?php
2+
/*
3+
* This file is part of the DateTime library.
4+
*
5+
* (c) Artem Henvald <genvaldartem@gmail.com>
6+
*
7+
* For the full copyright and license information, please view the LICENSE
8+
* file that was distributed with this source code.
9+
*/
10+
11+
declare(strict_types=1);
12+
13+
namespace Fresh\DateTime\Tests\Exception;
14+
15+
use Fresh\DateTime\Exception\ExceptionInterface;
16+
use Fresh\DateTime\Exception\InvalidArgumentException;
17+
use PHPUnit\Framework\Attributes\Test;
18+
use PHPUnit\Framework\TestCase;
19+
20+
/**
21+
* InvalidArgumentExceptionTest.
22+
*
23+
* @author Artem Henvald <genvaldartem@gmail.com>
24+
*/
25+
class InvalidArgumentExceptionTest extends TestCase
26+
{
27+
#[Test]
28+
public function constructor(): void
29+
{
30+
$invalidArgumentException = new InvalidArgumentException();
31+
$this->assertInstanceOf(\InvalidArgumentException::class, $invalidArgumentException);
32+
$this->assertInstanceOf(ExceptionInterface::class, $invalidArgumentException);
33+
}
34+
}

0 commit comments

Comments
 (0)