|
15 | 15 |
|
16 | 16 | use Closure;
|
17 | 17 | use const DATE_ATOM;
|
| 18 | +use DateInterval; |
18 | 19 | use DateTimeImmutable;
|
19 | 20 | use function is_array;
|
20 | 21 | use Laudis\Neo4j\Contracts\ConnectionInterface;
|
|
27 | 28 | use Laudis\Neo4j\Types\CypherMap;
|
28 | 29 | use Laudis\Neo4j\Types\Date;
|
29 | 30 | use Laudis\Neo4j\Types\DateTime;
|
| 31 | +use Laudis\Neo4j\Types\Duration; |
30 | 32 | use Laudis\Neo4j\Types\LocalDateTime;
|
31 | 33 | use Laudis\Neo4j\Types\LocalTime;
|
32 | 34 | use Laudis\Neo4j\Types\Node;
|
|
43 | 45 | use stdClass;
|
44 | 46 | use function str_pad;
|
45 | 47 | use const STR_PAD_RIGHT;
|
| 48 | +use function str_replace; |
| 49 | +use function str_starts_with; |
46 | 50 | use function strtolower;
|
47 | 51 | use UnexpectedValueException;
|
48 | 52 |
|
@@ -359,6 +363,10 @@ private function translateDateTime(string $datetime)
|
359 | 363 | return new DateTime($seconds, $nanoseconds, $offset);
|
360 | 364 | }
|
361 | 365 |
|
| 366 | + if (str_starts_with($datetime, 'P')) { |
| 367 | + return $this->durationFromFormat($datetime, $matches); |
| 368 | + } |
| 369 | + |
362 | 370 | throw new UnexpectedValueException(sprintf('Could not handle date/time "%s"', $datetime));
|
363 | 371 | }
|
364 | 372 |
|
@@ -420,4 +428,23 @@ private function addNanoSecondsToSeconds(int $nanoseconds, int $seconds): array
|
420 | 428 |
|
421 | 429 | return [$seconds, $nanoseconds];
|
422 | 430 | }
|
| 431 | + |
| 432 | + private function durationFromFormat(string $datetime): Duration |
| 433 | + { |
| 434 | + $nanoseconds = 0; |
| 435 | + // PHP date interval does not understand fractions of a second. |
| 436 | + if (preg_match('/\.(?<nanoseconds>\d+)S/u', $datetime, $matches)) { |
| 437 | + /** @var array{0: string, nanoseconds: string} $matches */ |
| 438 | + $nanoseconds = (int) str_pad($matches['nanoseconds'], 9, '0', STR_PAD_RIGHT); |
| 439 | + |
| 440 | + $datetime = str_replace($matches[0], 'S', $datetime); |
| 441 | + } |
| 442 | + |
| 443 | + $interval = new DateInterval($datetime); |
| 444 | + $months = (int) $interval->format('%y') * 12 + (int) $interval->format('%m'); |
| 445 | + $days = (int) $interval->format('%d'); |
| 446 | + $seconds = (int) $interval->format('%h') * 60 * 60 + (int) $interval->format('%i') * 60 + (int) $interval->format('%s'); |
| 447 | + |
| 448 | + return new Duration($months, $days, $seconds, $nanoseconds); |
| 449 | + } |
423 | 450 | }
|
0 commit comments