strtotime() 无法解析日期时间字符串中的“00:20 AM”

问题描述 投票:0回答:4

我想为 SQL 格式化日期,但我得到了意想不到的结果:

echo date('Y-m-d H:i:s', strtotime("February 13 2022 10:08 PM")); //2022-02-13 22:08:00
echo date('Y-m-d H:i:s', strtotime("March 23 2022 00:20 AM")); //1970-01-01 00:00:00

如何正确解析这些日期?

php date datetime datetime-format date-parsing
4个回答
1
投票

这是因为

strtotime("March 23 2022 00:20 AM")
返回 FALSE,因为它是 OMi Shah 指出的无效日期。显然
FALSE
0
函数评估为
date()
,尝试打印
date('Y-m-d H:i:s', FALSE);
并亲眼看看,它会打印
1970-01-01 03:00:00
date('Y-m-d H:i:s', 0);

相同

1
投票

如果你有无效的日期,你需要做错误检查:

$unixTime = strtotime('March 23 2022 00:20 AM');
if ($unixTime === false) {
    // Report error
} else {
    $normalizedString = date('Y-m-d H:i:s', $unixTime);
}

日期解析函数通常过于宽松(例如,

strtotime('PDT')
生成 PDT 时区的当前时间),因此转换回原始格式并查看是否返回相同的值也无妨。

您可能还想修复错误,但这在很大程度上取决于错误的外观以及您想要的解决方案:

'March 23 2022 00:20 AM' // Replace 00:... AM dates with valid representation
'February 31 2023 09:55 PM' // Make it March 3? Throw error?
'(no data)' // Nothing fixable here

1
投票

如果你的目标是修复数据,因为你的任务是使用有缺陷的数据,你可以使用正则表达式来切断任何犯规或不需要的

AM
PM
子串。

代码:(演示

$tests = [
    "February 13 2022 10:08 PM",
    "March 23 2022 00:20 AM",
    "April 3 2022 11:20 PM",
    "May 28 2022 12:20 AM",
    "June 12 2022 21:20 PM",
    "July 4 2022 13:20 AM",
];

$tests = preg_replace(
    [
        '/(?:0\d|1[01]):\d{2}\K AM/', // 00:00 through 11:59 do not need AM
        '/(?:2\d|1[3-9]):\d{2}\K [AP]M/',  // 13:00 through 23:59 do not need AM or PM
    ],
    '',
    $tests
);
var_export($tests);
foreach ($tests as $test) {
    echo "\n" . date('Y-m-d H:i:s', strtotime($test));
}

输出:

array (
  0 => 'February 13 2022 10:08 PM',
  1 => 'March 23 2022 00:20',
  2 => 'April 3 2022 11:20 PM',
  3 => 'May 28 2022 12:20 AM',
  4 => 'June 12 2022 21:20',
  5 => 'July 4 2022 13:20',
)
2022-02-13 22:08:00
2022-03-23 00:20:00
2022-04-03 23:20:00
2022-05-28 00:20:00
2022-06-12 21:20:00
2022-07-04 13:20:00

0
投票

总而言之,将 24 小时时间表示法与子午线指标 (AM/PM) 混合使用是有问题的。指标隐含 12 小时格式,其中 00:00 无效,从

strtotime
返回 false,并转换为 Unix 时间的开始

除了其他答案,考虑

DateTime::createFromFormat()

$timestamp1 = 'February 13 2022 10:08 PM';
$timestamp2 = 'March 23 2022 00:20 AM';

$date1 = DateTime::createFromFormat('F j Y H:i A',$timestamp1);
$date2 = DateTime::createFromFormat('F j Y H:i A',$timestamp2);

echo $date1->format('Y-m-d H:i:s');
echo PHP_EOL;
echo $date2->format('Y-m-d H:i:s');

输出:

2022-02-13 22:08:00
2022-03-23 00:20:00

在这里运行

© www.soinside.com 2019 - 2024. All rights reserved.