function validISO8601Date($value)
{
if (!is_string($value)) {
return false;
}
$dateTime = \DateTime::createFromFormat(\DateTime::ISO8601, $value);
if ($dateTime) {
return $dateTime->format(\DateTime::ISO8601) === $value;
}
return false;
}
注意了
一些有效的ISO8601日期将失败请查看下面的列表
NOT VALID --> '' // Correct
NOT VALID --> 'string' // Correct
VALID --> '2000-01-01T01:00:00+1200' // This is the only format function returns as valid
NOT VALID --> '2015-01 first' // Correct
NOT VALID --> '2000-01-01T01:00:00Z' // Must be valid!
NOT VALID --> '2000-01-01T01:00:00+01' // Must be valid!
if (preg_match('/^(\d{4})-(\d{2})-(\d{2})T(\d{2}):(\d{2}):(\d{2})(Z|(\+|-)\d{2}(:?\d{2})?)$/', $dateString, $parts)) {
// valid string format, can now check parts
$year = $parts[1];
$month = $parts[2];
$day = $parts[3];
// etc
}
use Carbon\Carbon;
use Carbon\Exceptions\InvalidFormatException;
...
/** @test */
public function checking_iso8601_date()
{
$this->expectException(InvalidFormatException::class);
Carbon::createFromFormat('c', '2021-05-11 20:03:45+02:00');
$this->assertInstanceOf(Carbon::class, Carbon::createFromFormat('c', '2021-05-11T20:03:45+02:00'));
}
您可以对DateTime执行相同的操作
use DateTime;
...
/** @test */
public function checking_iso8601_date()
{
$this->assertInstanceOf(DateTime::class, DateTime::createFromFormat('Y-m-d\TH:i:sP', '2021-05-11T20:03:45+02:00'));
$this->assertFalse(DateTime::createFromFormat('Y-m-d\TH:i:sP', '2021-05-11 20:03:45+02:00'));
}
6条答案
按热度按时间ljsrvy3e1#
这对我很有效,它使用正则表达式来确保日期是你想要的格式,然后尝试解析日期并重新创建它以确保输出与输入匹配:
您可以进一步扩展到使用checkdate来确保月、日和年也是有效的。
lmyy7pcs2#
我想分享我的轻量级解决方案。这并不理想,但可能对某人有帮助。
注意了
一些有效的ISO8601日期将失败请查看下面的列表
0s0u357o3#
**编辑:**到目前为止,最简单的方法是尝试使用字符串创建一个
DateTime
对象,例如如果
DateTime
构造函数不能解析字符串,它将抛出异常,例如DateTime::__construct():无法解析位置18(2)的时间字符串(2011-10- 02 T23:25:72 Z):意外字符
请注意,如果您不使用时区指示符,它将使用配置的默认时区。
第二个最简单的方法是使用正则表达式。像这样的东西足以掩盖它
zpqajqem4#
参见http://www.pelagodesign.com/blog/2009/05/20/iso-8601-date-validation-that-doesnt-suck/。它给出了这个正则表达式来用途:
我想这并没有完全回答你的问题,因为它将匹配任何有效的ISO 8601日期,但如果这是好的,那么这是完美的工作。
o2g1uqev5#
这是我使用的函数。它类似于drew 010的答案,但也适用于以“+01:00”或“-01:00”结尾的时间戳。
kknvjkwl6#
Carbon很好地处理了这部分
您可以对DateTime执行相同的操作