【问题标题】:Check if variable is a valid date with PHP检查变量是否是 PHP 的有效日期
【发布时间】:2012-05-21 20:13:29
【问题描述】:

我正在编写一个脚本,该脚本将从 CSV 文件中导入一些数据。当我这样做时,我希望能够检查一个变量,看看它是否是一个有效的日期字符串。

我已经看到了几种方法来检查一个字符串是否是一个日期,但其中大多数都需要你现在的格式。我不知道日期的格式。

现在我正在使用 strtotime(),但这并不容易

$field ="May";
if(strtotime($field)){
    echo "This is a date";
}

在这种情况下,“May”是人员的名字,根本不是日期。

谁能推荐更可靠的功能?

根据你们中的一些人提出的问题进行编辑。

在我的例子中,对于作为“日期”传递的变量,它需要特定于日/月/年,因此仅“五月”会含糊不清。

基于此和下面Pauls的好点我们也可以测试看看字符串中是否包含数字,比如

$field ="May";
if(strtotime($field) && 1 === preg_match('~[0-9]~', $field)){
    echo "This is a date";
}else{
    echo "Nope not a date";
}

这似乎满足了我的迫切需求,但是任何人都可以发现任何问题或提出改进建议吗?

【问题讨论】:

  • 您的脚本如何判断 May 是姓名还是日期?
  • 你需要给出一些规范你接受什么样的值。否则,“May”与任何其他值一样好。
  • 检查此人是否有姓
  • 有什么模式吗?月份是否以数字形式出现以及以字符串形式出现?日期是否在单元格中分隔,即 A1 中的月份,B2 中的日期,还是它们都在一个单元格中?
  • @Alex:仅匹配输入中的数字远不能令人满意,因为它可以将'0May' 作为有效日期。

标签: php date strtotime


【解决方案1】:

使用date_parse 并检查返回数组的值

$date = date_parse("May")

// ["year"] == FALSE
// ["month"] == 5
// ["day"] == FALSE

您也可以将它们传递给checkdate

$date = date_parse($someString);
if ($date["error_count"] == 0 && checkdate($date["month"], $date["day"], $date["year"]))
    echo "Valid date";
else
    echo "Invalid date";

【讨论】:

  • 我想你明白了......有人能看出这有什么缺陷吗?
  • 一个小缺陷:date_parse 使用strtotime 解析规则,即well-defined but finicky。可以提交返回合法日期但不是预期日期的数据。
  • @Charles 不需要明确定义的输入格式,任何自动解析日期的算法都会有问题
  • 我知道这是旧的,但如果你使用date_parse("2014-01-01 12:00:00'; select * from users;"),它会说日期是有效的。但是,$date['error_count'] 将大于 0,这可能是一个更好的选择。见ideone.com/Xl1HTb
  • @saluce $date["errors"] 是一个数组,因此它总是错误的。我想你需要的是$date["error_count"]
【解决方案2】:

我不认为这个问题有一个多合一的答案。根据您的用例,您可能有不同的策略。

您的strtotime() 是一个完美的解决方案,但正如您所说,您最终可能会误报。为什么?因为可能可能是一个词或一个名字。但是strtotime('May')的结果是什么?

echo date(DateTime::ISO8601, strtotime('May'));
2012-05-21T00:00:00+0200

因此,仅给出月份将返回当前年份的日期和当前日期,从给定月份的午夜开始。一个可能的解决方案是检查您的字符串是否包含当前日期和/或当前年份,这样,您可以检查以确保您的日期是完全合格的日期并且有效。

echo date(DateTime::ISO8601, strtotime('May Day')); // (strtotime() returns false)
1970-01-01T01:00:00+0100

echo date(DateTime::ISO8601, strtotime('May 21'));
2012-05-21T00:00:00+0200

一个简单的strpos() 甚至一个正则表达式都可以解决问题。

不过有点奇怪,只能在没有其他办法的情况下使用。

我认为更好的解决方案是定义一组有效格式并插入结果以确保日期有效。

$validDateFormatPatterns = array(
 '[0-9]{1,2}-[0-9]{1,2}-[0-9]{4}', // 21-05-2012, obviously this pattern is simple and would accept 05-21-2012,
 'the [0-9]{1,2}(th|st|nd|rd) (January|February|...|May|...|December) [0,9]{4}', // The 21st May 2012
);

您应该尝试涵盖大部分情况,我相信您将能够找到检查最新日期格式的正则表达式。

在任何情况下,您都可能需要不时调整您的功能,因为没有简单的方法使其防弹。

【讨论】:

    【解决方案3】:

    我知道这是很久以前问过的,但是四处寻找这个并试图避免正则表达式,我想出了这个:

    function checkInputIsDate($date) {
        return (bool)strpbrk($date,1234567890) && strtotime($date);
    }
    

    这是有效的,因为它通过确保字符串中有带有strpbrk 的数字以及验证strtotime 输出日期来消除上面发布的问题,即只有一个月传递到strtotime

    并了解了一个我不知道存在的功能。

    希望这对某人有所帮助。

    【讨论】:

      猜你喜欢
      • 2017-02-28
      • 2012-03-15
      • 1970-01-01
      • 2013-01-09
      • 2020-01-24
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2010-10-28
      相关资源
      最近更新 更多