我从API收到日期字符串,格式为yyyy-mm-dd
。
我目前正在使用正则表达式验证字符串格式,这可以正常工作,但我可以看到一些情况,根据字符串它可能是正确的格式,但实际上是无效的日期。例如,2013-13-01
。
有没有更好的方法在PHP中使用2013-13-01
之类的字符串,并告诉格式yyyy-mm-dd
它是否是有效日期?
答案 0 :(得分:380)
您可以使用DateTime
类来实现此目的:
function validateDate($date, $format = 'Y-m-d')
{
$d = DateTime::createFromFormat($format, $date);
// The Y ( 4 digits year ) returns TRUE for any integer with any number of digits so changing the comparison from == to === fixes the issue.
return $d && $d->format($format) === $date;
}
[取自this answer的函数。同样在php.net。最初由Glavić撰写。]
测试用例:
var_dump(validateDate('2013-13-01')); // false
var_dump(validateDate('20132-13-01')); // false
var_dump(validateDate('2013-11-32')); // false
var_dump(validateDate('2012-2-25')); // false
var_dump(validateDate('2013-12-01')); // true
var_dump(validateDate('1970-12-01')); // true
var_dump(validateDate('2012-02-29')); // true
var_dump(validateDate('2012', 'Y')); // true
var_dump(validateDate('12012', 'Y')); // false
答案 1 :(得分:68)
确定任何字符串是否为日期
function checkIsAValidDate($myDateString){
return (bool)strtotime($myDateString);
}
答案 2 :(得分:29)
使用php预建函数以简单的方式使用:
function checkmydate($date) {
$tempDate = explode('-', $date);
// checkdate(month, day, year)
return checkdate($tempDate[1], $tempDate[2], $tempDate[0]);
}
<强>测试强>
checkmydate('2015-12-01'); //true
checkmydate('2015-14-04'); //false
答案 3 :(得分:14)
确定字符串是否为日期,即使字符串是非标准格式
(strtotime不接受任何自定义格式)
var_dump
答案 4 :(得分:12)
这个选项不仅简单,而且几乎可以接受任何格式,但是对于非标准格式,它可能是错误的。
$timestamp = strtotime($date);
return $timestamp ? $date : null;
答案 5 :(得分:9)
您还可以解析月份日期和年份的日期,然后您可以使用PHP函数checkdate()
,您可以在此处阅读:http://php.net/manual/en/function.checkdate.php
你也可以尝试这个:
$date="2013-13-01";
if (preg_match("/^[0-9]{4}-(0[1-9]|1[0-2])-(0[1-9]|[1-2][0-9]|3[0-1])$/",$date))
{
echo 'Date is valid';
}else{
echo 'Date is invalid';
}
答案 6 :(得分:7)
根据cl-sah的回答,但这听起来更好,更短......
function checkmydate($date) {
$tempDate = explode('-', $date);
return checkdate($tempDate[1], $tempDate[2], $tempDate[0]);
}
测试
checkmydate('2015-12-01');//true
checkmydate('2015-14-04');//false
答案 7 :(得分:6)
我有这个东西,即使使用PHP,我也想找到功能性解决方案。因此,例如,@ migli给出的答案确实很好,非常灵活和优雅。
但它有一个问题:如果你需要用相同的格式验证很多DateTime字符串怎么办?你必须在整个地方重复这种格式,这与 DRY 原则背道而驰。我们可以将格式放在常量中,但是,我们必须将常量作为参数传递给每个函数调用。
但不要再害怕了!我们可以使用 currying 来救援! PHP不会使这个任务变得愉快,但仍然可以用PHP实现currying:
<?php
function validateDateTime($format)
{
return function($dateStr) use ($format) {
$date = DateTime::createFromFormat($format, $dateStr);
return $date && $date->format($format) === $dateStr;
};
}
那么,我们刚刚做了什么?基本上我们将函数体包装成匿名并返回这样的函数。我们可以像这样调用验证函数:
validateDateTime('Y-m-d H:i:s')('2017-02-06 17:07:11'); // true
是的,没有太大的区别......但真正的力量来自于部分应用的功能,这可以通过以下方式实现:
// Get a partially applied function
$validate = validateDateTime('Y-m-d H:i:s');
// Now you can use it everywhere, without repeating the format!
$validate('2017-02-06 17:09:31'); // true
$validate('1999-03-31 07:07:07'); // true
$validate('13-2-4 3:2:45'); // false
功能编程FTW!
答案 8 :(得分:5)
检查给定日期是否有效的最简单方法可能是使用<script>
var i = 0;
for (i = 0; i < 10; i++)
{
console.log("Text");
}
</script>
将其转换为unixtime,将其格式化为给定日期的格式,然后进行比较:
<script>
console.log("Text");
</script>
当然,您可以使用正则表达式来检查有效性,但它将限制为给定的格式,每次您必须编辑它以满足其他格式,并且它将超过要求。内置函数是实现工作的最佳方式(在大多数情况下)。
答案 9 :(得分:3)
这个怎么样?
我们只使用try-catch块。
ConfigureAwait(false)
此方法不仅限于一种日期/时间格式,您无需定义任何功能。
答案 10 :(得分:1)
经过测试的Regex解决方案:
function isValidDate($date)
{
if (preg_match("/^(((((1[26]|2[048])00)|[12]\d([2468][048]|[13579][26]|0[48]))-((((0[13578]|1[02])-(0[1-9]|[12]\d|3[01]))|((0[469]|11)-(0[1-9]|[12]\d|30)))|(02-(0[1-9]|[12]\d))))|((([12]\d([02468][1235679]|[13579][01345789]))|((1[1345789]|2[1235679])00))-((((0[13578]|1[02])-(0[1-9]|[12]\d|3[01]))|((0[469]|11)-(0[1-9]|[12]\d|30)))|(02-(0[1-9]|1\d|2[0-8])))))$/", $date)) {
return $date;
}
return null;
}
如果日期无效或不是yyyy-mm-dd格式,则返回null,否则返回日期。
答案 11 :(得分:0)
Layer
答案 12 :(得分:0)
恐怕多数投票解决方案(https://stackoverflow.com/a/19271434/3283279)无法正常工作。第四个测试用例(var_dump(validateDate('2012-2-25')); //否)错误。日期是正确的,因为它与格式相对应- m 允许一个月带或不带的前导零(请参见:http://php.net/manual/en/datetime.createfromformat.php)。因此,日期 2012-2-25 的格式为 Y-m-d ,并且测试用例必须为true而不是false。
我相信更好的解决方案是按如下方式测试可能的错误:
function validateDate($date, $format = 'Y-m-d') {
DateTime::createFromFormat($format, $date);
$errors = DateTime::getLastErrors();
return $errors['warning_count'] === 0 && $errors['error_count'] === 0;
}
答案 13 :(得分:0)
使用检查日期功能进行验证:
$date = '2019-02-30';
$date_parts = explode( '-', $date );
if(checkdate( $date_parts[1], $date_parts[2], $date_parts[0] )){
//date is valid
}else{
//date is invalid
}
答案 14 :(得分:0)
要添加到已接受的答案中,您可以通过检查格式化日期是否为 instanceof
DateTime
来进一步检查有效日期或 DateTime。
$date = DateTime::createFromFormat('Ymd', $value);
$is_datetime = ($date instanceof DateTime);
$is_valid_datetime_format = $is_datetime
? ($date->format('Ymd') === $value)
: false;
if (!$is_datetime || !$is_valid_datetime_format) {
// Not a valid date.
return false;
}
这将捕获任何不是 DateTime
的值,例如随机字符串或无效日期,例如 20202020
。
答案 15 :(得分:-1)
/**** date check is a recursive function. it's need 3 argument
MONTH,DAY,YEAR. ******/
$always_valid_date = $this->date_check($month,$day,$year);
private function date_check($month,$day,$year){
/** checkdate() is a php function that check a date is valid
or not. if valid date it's return true else false. **/
$status = checkdate($month,$day,$year);
if($status == true){
$always_valid_date = $year . '-' . $month . '-' . $day;
return $always_valid_date;
}else{
$day = ($day - 1);
/**recursive call**/
return $this->date_check($month,$day,$year);
}
}
答案 16 :(得分:-1)
尝试一下:
$date = "2017-10-01";
function date_checker($input,$devider){
$output = false;
$input = explode($devider, $input);
$year = $input[0];
$month = $input[1];
$day = $input[2];
if (is_numeric($year) && is_numeric($month) && is_numeric($day)) {
if (strlen($year) == 4 && strlen($month) == 2 && strlen($day) == 2) {
$output = true;
}
}
return $output;
}
if (date_checker($date, '-')) {
echo "The function is working";
}else {
echo "The function isNOT working";
}