将influxdb时间格式转换为ISO8601格式
Convert influxdb time format to ISO8601 format
当使用 influxdb PHP 客户端时,我看到这种时间格式具有纳秒精度:
2020-02-06T17:26:38.277740846Z
PHP DateTime 格式好像不太懂:
$date = DateTime::createFromFormat("Y-m-d\TH:i:s.u?",$time);
我得到 false
作为 return 值。
如何将其转换为 ISO8601 或自定义格式?
由于 PHP 日期处理的时间不超过微秒,您可以使用 +
说明符
忽略微秒 6 位数字后的其余字符串
来自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.
如果您的日期总是以 'Z' 结尾,您可以强制使用 UTC 时区:
$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
DateTime 最多只接受 6 位微秒。字母 Z 代表时区。如果删除多余的数字,则必须使用第3个参数将时区设置为Z。
$time = '2020-02-06T17:26:38.277740846Z';
$dateTime = DateTime::createFromFormat('Y-m-d\TH:i:s.u???\Z',$time,new DateTimeZone('Z'));
然后将 DateTime 对象转换为自定义格式非常容易。
echo $dateTime->format("Y-m-d H:i:s.v");
//2020-02-06 17:26:38.277
嗯,大多数时候,人们不需要那么多纳秒级的精度。
就我而言,只需几秒钟。
根据我的经验,忽略 InfluxDb 测量的精确设置(大多数用户会这样做......),导致纳秒数字不一致,导致转换失败。
因此,由于 PHP DateTime 在格式不一致时失败,为什么不将纳秒默认限制为 6 位?
我这样做了:
$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';
从 PHP8 开始,DateTime 构造函数将不再阻塞此输入格式。不过会truncate the nanosecond precision to microseconds (6 places)。
代码:(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
当使用 influxdb PHP 客户端时,我看到这种时间格式具有纳秒精度:
2020-02-06T17:26:38.277740846Z
PHP DateTime 格式好像不太懂:
$date = DateTime::createFromFormat("Y-m-d\TH:i:s.u?",$time);
我得到 false
作为 return 值。
如何将其转换为 ISO8601 或自定义格式?
由于 PHP 日期处理的时间不超过微秒,您可以使用 +
说明符
来自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.
如果您的日期总是以 'Z' 结尾,您可以强制使用 UTC 时区:
$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
DateTime 最多只接受 6 位微秒。字母 Z 代表时区。如果删除多余的数字,则必须使用第3个参数将时区设置为Z。
$time = '2020-02-06T17:26:38.277740846Z';
$dateTime = DateTime::createFromFormat('Y-m-d\TH:i:s.u???\Z',$time,new DateTimeZone('Z'));
然后将 DateTime 对象转换为自定义格式非常容易。
echo $dateTime->format("Y-m-d H:i:s.v");
//2020-02-06 17:26:38.277
嗯,大多数时候,人们不需要那么多纳秒级的精度。 就我而言,只需几秒钟。 根据我的经验,忽略 InfluxDb 测量的精确设置(大多数用户会这样做......),导致纳秒数字不一致,导致转换失败。 因此,由于 PHP DateTime 在格式不一致时失败,为什么不将纳秒默认限制为 6 位?
我这样做了:
$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';
从 PHP8 开始,DateTime 构造函数将不再阻塞此输入格式。不过会truncate the nanosecond precision to microseconds (6 places)。
代码:(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