Skip to content
New issue

Have a question about this project? # for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “#”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? # to your account

[PHP] Merging of Timestamp field from JSON string results in wrong seconds #4335

Closed
bitevo opened this issue Feb 25, 2018 · 6 comments
Closed

Comments

@bitevo
Copy link

bitevo commented Feb 25, 2018

Merging of Timestamp field from JSON string results in wrong seconds. In my test, it was off by 1 sec for microsecond resolution string and even worse for nanosecond resolution string.

Test output (run on MacOS High Sierra):

PHP Version: 7.1.7

Original as string : 2018-02-25T03:48:17.428086+00:00
Original seconds   : 1519530497.428086

Convert nano string to/from JSON:
Nano input string  : 2018-02-25T03:48:17.428086000Z
JS Decoded seconds : 1519530490
JS Decoded nanos   : 428086000

Convert to and from protobuf:
Pre-enc seconds   : 1519530497
Pre-enc nanos     : 428086
PB Decoded sec    : 1519530497
PB Decoded nsec   : 428086

Convert to and from JSON:
JS Decoded sec    : 1519530496
JS Decoded nsec   : 428086

The issue described here is about correctness, not precision. I know PHP doesn't natively support nano second, but string parsing should not be affected by that. There will be lost of precision during conversion from string to PHP DateTime object, but the number of seconds should be always correct.

The proto file I used in the test:

syntax = "proto3";

import "google/protobuf/timestamp.proto";

message Sample {
  google.protobuf.Timestamp timestamp = 1;
}

PHP test script (using compiled PHP class):

$timestamp = new \DateTime('2018-02-25T03:48:17.428086', new \DateTimeZone('UTC'));
$gpbTimestamp = new \Google\Protobuf\Timestamp();
$gpbTimestamp->setSeconds((int) $timestamp->format('U'));
$gpbTimestamp->setNanos((int) $timestamp->format('u'));
echo "PHP Version: ", PHP_VERSION, PHP_EOL;
echo PHP_EOL;
echo "Original as string : ", $timestamp->format('Y-m-d\TH:i:s.uP'), PHP_EOL;
echo "Original seconds   : ", $timestamp->format('U.u'), PHP_EOL;
echo PHP_EOL;

echo "Convert nano string to/from JSON:", PHP_EOL;
$nanoArray = [
    'timestamp' => $timestamp->format('Y-m-d\TH:i:s.u') . '000Z',
];
$message = new Sample();
$message->mergeFromJsonString(json_encode($nanoArray));
echo "Nano input string  : ", $nanoArray['timestamp'], PHP_EOL;
echo "JS Decoded seconds : ", $message->getTimestamp()->getSeconds(), PHP_EOL;
echo "JS Decoded nanos   : ", $message->getTimestamp()->getNanos(), PHP_EOL;
echo PHP_EOL;

echo "Convert to and from protobuf:", PHP_EOL;
$message = new Sample(); // ensure clear start
$message->setTimestamp($gpbTimestamp);
echo "Pre-enc seconds   : ", $message->getTimestamp()->getSeconds(), PHP_EOL;
echo "Pre-enc nanos     : ", $message->getTimestamp()->getNanos(), PHP_EOL;
$pbEnc = $message->serializeToString();
$message = new Sample(); // ensure clear start
$message->mergeFromString($pbEnc);
echo "PB Decoded sec    : ", $message->getTimestamp()->getSeconds(), PHP_EOL;
echo "PB Decoded nsec   : ", $message->getTimestamp()->getNanos(), PHP_EOL;
echo PHP_EOL;

echo "Convert to and from JSON:", PHP_EOL;
$message = new Sample(); // ensure clear start
$message->setTimestamp($gpbTimestamp);
$jsonEnc = $message->serializeToJsonString();
$message = new Sample(); // ensure clear start
$message->mergeFromJsonString($jsonEnc);
echo "JS Decoded sec    : ", $message->getTimestamp()->getSeconds(), PHP_EOL;
echo "JS Decoded nsec   : ", $message->getTimestamp()->getNanos(), PHP_EOL;
@shogochiai
Copy link

shogochiai commented Feb 25, 2018

For elaborating this issue, I want to clarify these.

  1. JSON convert and Protobuf convert are using different logic to convert timestamp, and this is plugin, and (maybe) not tested well on protobuf-php

  2. Those “logics” may be in mergeFromJsonString, serializeToString and serializeToJsonString.

  3. fromDatetime, toDatetime, getSeconds, setSeconds, getNanos and setNanos are tested on php-timestamp-adaptor side, but we cannot confirm that is enough test case for No.2 mentioned functions (https://github.com/google/protobuf/blob/77f64bb7779ec2195f9bc4dc82497d12c18fc6b7/php/tests/well_known_test.php#L302-L320)

Is this gonna be critical path? If so, we'd better to put enough test case on these related funcs.

@TeBoring
Copy link
Contributor

Are you using c extension?

@bitevo
Copy link
Author

bitevo commented Mar 2, 2018

@TeBoring I didn't use the C ext. I used the PHP script (google/protobuf v3.5.1.1).

@bitevo
Copy link
Author

bitevo commented Mar 8, 2018

Just in case you need it, you can find the test files as composer project on https://github.com/sbhalim/protobuf-issue-4335

@TeBoring TeBoring added this to the v3.7.0 milestone Dec 1, 2018
@TeBoring
Copy link
Contributor

TeBoring commented Jan 9, 2019

@bitevo In your example, $timestamp->format('u') is usec. It should be multiplied by 1000.

TeBoring added a commit to TeBoring/protobuf that referenced this issue Jan 9, 2019
@TeBoring
Copy link
Contributor

TeBoring commented Jan 9, 2019

Can't reproduce. Maybe this has been fixed.

@TeBoring TeBoring closed this as completed Jan 9, 2019
copybara-service bot pushed a commit that referenced this issue Jan 31, 2024
Protobuf php lib encodes 123_000_000 nano like this: 2000-01-01T00:00:00.**123**Z but then it gets decoded into 123 nanoseconds instead of 123_000_000.

There were issue opened some time ago that also describes this behaviour #4335

Closes #12396

COPYBARA_INTEGRATE_REVIEW=#12396 from kindratmakc:bugfix/inconsistent-timestamp-json-encode-decode df47c96
FUTURE_COPYBARA_INTEGRATE_REVIEW=#12396 from kindratmakc:bugfix/inconsistent-timestamp-json-encode-decode df47c96
PiperOrigin-RevId: 603110109
copybara-service bot pushed a commit that referenced this issue Jan 31, 2024
Protobuf php lib encodes 123_000_000 nano like this: 2000-01-01T00:00:00.**123**Z but then it gets decoded into 123 nanoseconds instead of 123_000_000.

There were issue opened some time ago that also describes this behaviour #4335

Closes #12396

COPYBARA_INTEGRATE_REVIEW=#12396 from kindratmakc:bugfix/inconsistent-timestamp-json-encode-decode df47c96
FUTURE_COPYBARA_INTEGRATE_REVIEW=#12396 from kindratmakc:bugfix/inconsistent-timestamp-json-encode-decode df47c96
PiperOrigin-RevId: 603110109
copybara-service bot pushed a commit that referenced this issue Jan 31, 2024
Protobuf php lib encodes 123_000_000 nano like this: 2000-01-01T00:00:00.**123**Z but then it gets decoded into 123 nanoseconds instead of 123_000_000.

There were issue opened some time ago that also describes this behaviour #4335

Closes #12396

COPYBARA_INTEGRATE_REVIEW=#12396 from kindratmakc:bugfix/inconsistent-timestamp-json-encode-decode df47c96
PiperOrigin-RevId: 603118615
zhangskz pushed a commit that referenced this issue Feb 5, 2024
Protobuf php lib encodes 123_000_000 nano like this: 2000-01-01T00:00:00.**123**Z but then it gets decoded into 123 nanoseconds instead of 123_000_000.

There were issue opened some time ago that also describes this behaviour #4335

Closes #12396

COPYBARA_INTEGRATE_REVIEW=#12396 from kindratmakc:bugfix/inconsistent-timestamp-json-encode-decode df47c96
PiperOrigin-RevId: 603118615
zhangskz added a commit that referenced this issue Feb 5, 2024
Protobuf php lib encodes 123_000_000 nano like this: 2000-01-01T00:00:00.**123**Z but then it gets decoded into 123 nanoseconds instead of 123_000_000.

There were issue opened some time ago that also describes this behaviour #4335

Closes #12396

COPYBARA_INTEGRATE_REVIEW=#12396 from kindratmakc:bugfix/inconsistent-timestamp-json-encode-decode df47c96
PiperOrigin-RevId: 603118615

Co-authored-by: kindratmakc <kindratmakc@gmail.com>
deannagarcia pushed a commit to deannagarcia/protobuf that referenced this issue Jun 20, 2024
Protobuf php lib encodes 123_000_000 nano like this: 2000-01-01T00:00:00.**123**Z but then it gets decoded into 123 nanoseconds instead of 123_000_000.

There were issue opened some time ago that also describes this behaviour protocolbuffers#4335

Closes protocolbuffers#12396

COPYBARA_INTEGRATE_REVIEW=protocolbuffers#12396 from kindratmakc:bugfix/inconsistent-timestamp-json-encode-decode df47c96
PiperOrigin-RevId: 603118615
# for free to join this conversation on GitHub. Already have an account? # to comment
Projects
None yet
Development

No branches or pull requests

4 participants