HyperDevil
HyperDevil

Reputation: 2649

Convert influxdb time format to ISO8601 format

When using the influxdb PHP client I see this time format with nanosecond precision:

2020-02-06T17:26:38.277740846Z

PHP DateTime does not seem to understand the format:

$date = DateTime::createFromFormat("Y-m-d\TH:i:s.u?",$time);

I get false as the return value.

How can I convert this to ISO8601 or a custom format?

Upvotes: 1

Views: 1502

Answers (4)

mickmackusa
mickmackusa

Reputation: 48011

From PHP8, the DateTime constructor will no longer choke on this input format. It will truncate the nanosecond precision to microseconds (6 places) though.

Code: (Demo)

$dt = '2020-02-06T17:26:38.277740846Z';
echo (new DateTime($dt))->format('Y-m-d H:i:s');
// 2020-02-06 17:26:38

Upvotes: 1

Dan Radu
Dan Radu

Reputation: 1

Well, most of the time, people don't need so much precision on nanoseconds. In my case, just seconds. In my experience, ignoring precision setup on InfluxDb measurements(most users will do that...), results in inconsistent number of nanoseconds digits, leading to failure in conversion. So, because PHP DateTime fails on inconsistent formats, why not restrict nanoseconds to 6 digits by default?

I did this:

$influxDbDate ="2020-02-06T17:26:38.277740846Z"
$outformat = '%F %T'; //equivalent of 'Y-m-d H:i:s' or you could get just date with 'Y-m-d' and so on...
$datePortions = explode('.', $influxDbDate);
$remadeTime = $datePortions[0] . '.' . substr(explode('Z', $datePortions[1])[0], 0, 6) . 'Z';
$dateTime = DateTime::createFromFormat('Y-m-d\TH:i:s.u\Z', $remadeTime, new DateTimeZone('Z'));
if ($dateTime)
  $result = strftime($outformat, $dateTime->getTimestamp());
else
$result = $remadeTime . ' is not InfluxDb timeformat';

Upvotes: 0

jspit
jspit

Reputation: 7703

DateTime only accepts a maximum of 6 digits for the microseconds. The letter Z represents a time zone. If the surplus digits are removed, the time zone must be set to Z with the 3rd parameter.

$time = '2020-02-06T17:26:38.277740846Z';

$dateTime = DateTime::createFromFormat('Y-m-d\TH:i:s.u???\Z',$time,new DateTimeZone('Z'));

Converting the DateTime object to a custom format is then very easy.

echo $dateTime->format("Y-m-d H:i:s.v");
//2020-02-06 17:26:38.277

Upvotes: 3

Joffrey Schmitz
Joffrey Schmitz

Reputation: 2438

As PHP dates don't handle more than the microseconds, you can ignore the rest of your string after the 6 digits of the microseconds with the + specifier

From the documentation :

+

If this format specifier is present, trailing data in the string will not cause an error, but a warning instead

Use DateTime::getLastErrors() to find out whether trailing data was present.

If your dates always end with 'Z', you can force the UTC timezone :

$time = '2020-02-06T17:26:38.277740846Z' ;
$date = DateTime::createFromFormat("Y-m-d\TH:i:s.u+", $time, new DateTimeZone('UTC'));
echo $date->format('c'); // 2020-02-06T17:26:38+00:00

Upvotes: 1

Related Questions