orisai / object-mapper

Raw data mapping to validated objects
Mozilla Public License 2.0
10 stars 1 forks source link

Nanoseconds date precision #68

Open mrceperka opened 1 year ago

mrceperka commented 1 year ago

Library version

v1.x-dev

Description

Go serializes time to 2023-07-14T13:52:32.489932695Z. This includes nanoseconds. PHP is not able to handle nanoseconds and JsIsoFormat fails.

Steps to reproduce

This is probably general PHP problem.

$v = '2023-07-14T13:52:32.489932695Z';
$d = DateTimeImmutable::createFromFormat('Y-m-d\TH:i:s.v\Z', $v, new DateTimeZone('UTC'));
var_dump($d); // false

Actual Behavior

DateTimeValue will say it is not valid date

Expected Behavior

Validation should pass. We can strip those nanos, cos PHP does not support them either (AI said that :D)

Addition information

AI would solve it like this (this works with u instead of v tho)

$timestamp = '2023-07-14T15:43:41.453Z'; // Millisecond precision

// Separate the fractional part
list($whole, $fraction) = explode('.', $timestamp);

// Add trailing zeros or truncate to fit 6 digits
$fraction = substr(str_pad($fraction, 6, '0'), 0, 6);

// Combine everything
$timestampMicro = "$whole.$fraction" . "Z";

// Now parse it with DateTime::createFromFormat
$date = DateTime::createFromFormat('Y-m-d\TH:i:s.u\Z', $timestampMicro);

echo $date->format('Y-m-d H:i:s.u');  // Outputs '2023-07-14 15:43:41.453000'
mabar commented 1 year ago

JS format should already work with default DateTimeValue format. Go format seems to be just a bit more precise? It may work already.

But we should definitely add some tests for created datetime to check how accurate is the result

https://github.com/orisai/object-mapper/blob/e974721d8c8d6008ae811c107bd8e7db942fe2fa/src/Rules/DateTimeRule.php#L134-L136 https://github.com/orisai/object-mapper/blob/e974721d8c8d6008ae811c107bd8e7db942fe2fa/tests/Unit/Rules/DateTimeRuleTest.php#L70 https://github.com/orisai/object-mapper/tree/e974721d8c8d6008ae811c107bd8e7db942fe2fa/docs#datetime-rule