【问题标题】:Parsing postgres datetime with timezone with optional microseconds使用可选微秒的时区解析 postgres 日期时间
【发布时间】:2018-03-04 12:31:14
【问题描述】:

我想通过DateTime::createFromFormat() 解析带有时区的 postgres 日期时间。但是不知道$format参数怎么写。

$dates = [
    '2016-03-04 10:29:40+01',
    '2016-03-04 10:29:40.123456+01',
];

$format = 'Y-m-d H:i:s.uP';

foreach ($dates as $value) {
    $dt = DateTime::createFromFormat($format, $value);
    var_dump($dt);
}
bool(false)

object(DateTime)#2 (3) {
  ["date"]=>
  string(26) "2016-03-04 10:29:40.123456"
  ["timezone_type"]=>
  int(1)
  ["timezone"]=>
  string(6) "+01:00"
}

第一个日期不解析,第二个是。

【问题讨论】:

    标签: php postgresql datetime date-formatting


    【解决方案1】:

    编辑

    如果您只想要DateTime::createFromFormat() 解决方案,您将面临一个问题:createFromFormat() 不支持可选部分。没有办法直接解析可能有微秒的字符串。

    您可以做的一个技巧是搜索用于ms 部分的.,并即时更改您的模式:

    <?
    $dates = [
        '2016-03-04 10:29:40+01',
        '2016-03-04 10:29:40.123456+01',
    ];
    
    foreach ($dates as $value) {
        $format = (strpos($value,'.')===FALSE) ?'Y-m-d H:i:sP':'Y-m-d H:i:s.uP';
        $dt = DateTime::createFromFormat($format, $value);
        var_dump($dt);
    }
    

    如果您无法使用Postgresql::to_char() 格式化输出,PHP::strtotime() 可能是最好的解决方案

    <?
    echo date('Y-m-d H:i:s.uP', strtotime('2016-03-04 10:29:40+01'));
    // 2016-03-04 01:29:40.000000-08:00
    
    echo date('Y-m-d H:i:s.uP', strtotime('2016-03-04 10:29:40.123456+01'));
    // 2016-03-04 01:29:40.000000-08:00
    

    【讨论】:

    • 谢谢,我知道这个解决方案,但我需要DateTime::createFromFormat() 方式
    • @venca 更新了,即使解决方案有点难看……你不能用Postgresql::to_char() 直接用postgresql 删除ms 部分吗?
    • 我在代码Zend\Hydrator\Strategy\DateTimeFormatterStrategy 的很多地方都使用过,所以最简单的解决方案是找到正确的$format。我尝试了特殊字符,例如?,但没有成功,我不确定是否无法使用可选部分创建格式。
    • @venca 好吧,我可能不太清楚:没有正确的格式可以让您在使用和不使用ms 的情况下补充水分。要么将它们放在数据库端,要么破解为它们补充水分的方式。 'Y-m-d H:i:s+' 是你可以去的最接近的地方,它会放弃你的时区,远非完美......
    猜你喜欢
    • 1970-01-01
    • 2021-09-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-12-14
    相关资源
    最近更新 更多