|
15 | 15 |
|
16 | 16 | use function array_key_first;
|
17 | 17 | use Closure;
|
| 18 | +use DateTimeImmutable; |
18 | 19 | use function is_array;
|
19 | 20 | use Laudis\Neo4j\Contracts\ConnectionInterface;
|
20 | 21 | use Laudis\Neo4j\Contracts\PointInterface;
|
|
24 | 25 | use Laudis\Neo4j\Types\CartesianPoint;
|
25 | 26 | use Laudis\Neo4j\Types\CypherList;
|
26 | 27 | use Laudis\Neo4j\Types\CypherMap;
|
| 28 | +use Laudis\Neo4j\Types\Date; |
| 29 | +use Laudis\Neo4j\Types\LocalTime; |
27 | 30 | use Laudis\Neo4j\Types\Node;
|
28 | 31 | use Laudis\Neo4j\Types\Path;
|
29 | 32 | use Laudis\Neo4j\Types\Relationship;
|
| 33 | +use Laudis\Neo4j\Types\Time; |
30 | 34 | use Laudis\Neo4j\Types\UnboundRelationship;
|
31 | 35 | use Laudis\Neo4j\Types\WGS843DPoint;
|
32 | 36 | use Laudis\Neo4j\Types\WGS84Point;
|
| 37 | +use function preg_match; |
33 | 38 | use Psr\Http\Message\RequestInterface;
|
34 | 39 | use Psr\Http\Message\ResponseInterface;
|
35 | 40 | use stdClass;
|
| 41 | +use function str_pad; |
| 42 | +use const STR_PAD_RIGHT; |
36 | 43 | use function strtolower;
|
37 | 44 | use UnexpectedValueException;
|
38 | 45 |
|
@@ -120,10 +127,32 @@ private function translateJoltType(?stdClass $value)
|
120 | 127 |
|
121 | 128 | /**
|
122 | 129 | * @return OGMTypes
|
| 130 | + * |
| 131 | + * @psalm-suppress ImpureMethodCall |
| 132 | + * @psalm-suppress PossiblyFalseReference |
123 | 133 | */
|
124 | 134 | private function translateDateTime(string $datetime)
|
125 | 135 | {
|
126 |
| - // TODO; They're in ISO format so shouldn't be too hard |
| 136 | + if (preg_match('/^\d+-\d{2}-\d{2}$/', $datetime)) { |
| 137 | + $date = DateTimeImmutable::createFromFormat('Y-m-d', $datetime); |
| 138 | + |
| 139 | + return new Date((int) $date->diff(new DateTimeImmutable('@0'))->format('%a')); |
| 140 | + } |
| 141 | + |
| 142 | + if (preg_match('/^(\d{2}):(\d{2}):(\d{2})((\.)(\d+))?$/', $datetime, $matches)) { |
| 143 | + $nanoseconds = $this->nanosecondsFromMatches($matches); |
| 144 | + |
| 145 | + return new LocalTime($nanoseconds); |
| 146 | + } |
| 147 | + |
| 148 | + if (preg_match('/^(\d{2}):(\d{2}):(\d{2})((\.)(\d+))?(?<zone>[\w\W])+$/', $datetime, $matches)) { |
| 149 | + $nanoseconds = $this->nanosecondsFromMatches($matches); |
| 150 | + |
| 151 | + $offset = $this->offsetFromMatches($matches); |
| 152 | + |
| 153 | + return new Time($nanoseconds, $offset); |
| 154 | + } |
| 155 | + |
127 | 156 | throw new UnexpectedValueException('Date/time values have not been implemented yet');
|
128 | 157 | }
|
129 | 158 |
|
@@ -307,4 +336,27 @@ private function translateBinary(): Closure
|
307 | 336 | {
|
308 | 337 | throw new UnexpectedValueException('Binary data has not been implemented');
|
309 | 338 | }
|
| 339 | + |
| 340 | + private function nanosecondsFromMatches(array $matches): int |
| 341 | + { |
| 342 | + /** @var array{0: string, 1: string, 2: string, 3: string, 4?: array{0: string, 1: string}} $matches */ |
| 343 | + $seconds = ((int) $matches[1]) * 60 * 60 + ((int) $matches[2]) * 60 + ((int) $matches[3]); |
| 344 | + $nanoseconds = $matches[4][1] ?? '0'; |
| 345 | + $nanoseconds = str_pad($nanoseconds, 9, '0', STR_PAD_RIGHT); |
| 346 | + |
| 347 | + return $seconds * 1000 * 1000 * 1000 + (int) $nanoseconds; |
| 348 | + } |
| 349 | + |
| 350 | + private function offsetFromMatches(array $matches): int |
| 351 | + { |
| 352 | + /** @var array{zone: string} $matches */ |
| 353 | + $zone = $matches['zone']; |
| 354 | + |
| 355 | + if (preg_match('/(\d{2}):(\d{2})/', $zone, $matches)) { |
| 356 | + /** @var array{0: string, 1: string, 2: string} $matches */ |
| 357 | + return ((int) $matches[1]) * 60 + (int) $matches[2]; |
| 358 | + } |
| 359 | + |
| 360 | + return 0; |
| 361 | + } |
310 | 362 | }
|
0 commit comments