diff --git a/src/BSON/UTCDateTime.c b/src/BSON/UTCDateTime.c index c9f8d1eb4..b9b7246eb 100644 --- a/src/BSON/UTCDateTime.c +++ b/src/BSON/UTCDateTime.c @@ -223,11 +223,12 @@ static PHP_METHOD(MongoDB_BSON_UTCDateTime, toDateTime) object_init_ex(return_value, php_date_get_date_ce()); datetime_obj = Z_PHPDATE_P(return_value); - sec_len = spprintf(&sec, 0, "@%" PRId64, intern->milliseconds / 1000); + /* Initialize a DateTime using "Unix Timestamp with microseconds" notation. + * PHP 7.4 expects exactly six points of precision to denote microseconds. + * PHP 8.0+ accepts between zero and six points of precision. */ + sec_len = spprintf(&sec, 0, "@%" PRId64 ".%.6d", intern->milliseconds / 1000, abs((int) (intern->milliseconds % 1000) * 1000)); php_date_initialize(datetime_obj, sec, sec_len, NULL, NULL, 0); efree(sec); - - datetime_obj->time->us = (intern->milliseconds % 1000) * 1000; } static PHP_METHOD(MongoDB_BSON_UTCDateTime, jsonSerialize) diff --git a/tests/bson/bson-utcdatetime-todatetime-003.phpt b/tests/bson/bson-utcdatetime-todatetime-003.phpt new file mode 100644 index 000000000..df4bdfa9d --- /dev/null +++ b/tests/bson/bson-utcdatetime-todatetime-003.phpt @@ -0,0 +1,22 @@ +--TEST-- +MongoDB\BSON\UTCDateTime::toDateTime() with dates before the Unix epoch +--INI-- +date.timezone=UTC +--FILE-- +format('Y-m-d H:i:s.u'), PHP_EOL; + +$utcdatetime = new MongoDB\BSON\UTCDateTime($date); + +$newDate = $utcdatetime->toDateTime(); +echo $newDate->format('Y-m-d H:i:s.u'), PHP_EOL; + +?> +===DONE=== + +--EXPECT-- +1960-01-01 12:12:12.100000 +1960-01-01 12:12:12.100000 +===DONE===