For clarity, let's consider the following use case:
You need to convert a string in the simplified extended ISO 8601 format (e.g. returned by Javascript's Date.prototype.toISOString()
) to and from PHP's MongoDate
object, while preserving maximum precision during conversion.
In this format, the string is always 24 characters long: YYYY-MM-DDTHH:mm:ss.sssZ
. The timezone is always zero UTC offset, as denoted by the suffix Z
.
To keep milliseconds, we'll have to leverage PHP's DateTime
object.
From string to MongoDate
:
$stringDt = "2015-10-07T14:28:41.545Z";
Method 1 (using date_create_from_format
):
$phpDt = date_create_from_format('Y-m-d\TH:i:s.uP', $stringDt);
$MongoDt = new \MongoDate($phpDt->getTimestamp(), $phpDt->format('u'));
Method 2 (using strtotime
):
$MongoDt= new \MongoDate(strtotime ($stringDt),
1000*intval(substr($stringDt, -4, 3)) // cut msec portion, convert msec to usec
);
From MongoDate
to string:
$MongoDt = new \MongoDate(); // let's take now for example
$stringDt =
substr(
(new \DateTime())
->setTimestamp($MongoDt->sec)
->setTimeZone(new \DateTimeZone('UTC'))
->format(\DateTime::ISO8601),
0, -5) // taking the beginning of DateTime::ISO8601-formatted string
.sprintf('.%03dZ', $MongoDt->usec / 1000); // adding msec portion, converting usec to msec
Hope this helps.