PHP检查有效日期,奇怪的日期转换

时间:2020-03-06 14:48:04  来源:igfitidea点击:

有没有一种方法可以检查日期/时间是否有效,我们会认为这些方法很容易检查:

$date = '0000-00-00';
$time = '00:00:00';
$dateTime = $date . ' ' . $time;

if(strtotime($dateTime)) {
    // why is this valid?
}

真正让我着迷的是:

echo date('Y-m-d', strtotime($date));

结果为:" 1999-11-30",

??我从注册簿转到了1999-11-30 ???

我知道我可以进行比较,以查看日期是否是这些值中的任何一个都等于我拥有的日期,但这不是一种非常可靠的检查方法。有没有一种好的方法来检查我是否有有效的日期?任何人都有很好的功能来检查吗?

编辑:
人们问我在跑什么:
在Linux本地主机2.6.18-53.1.14.el5#1 SMP上于Linux localhost 2.6.18-53.1.14.el5上运行PHP 5.2.5(cli)(星期三)3月5日11:36:49 EST 2008 i686 i686 i386 GNU /的Linux

解决方案

echo date('Y-m-d', strtotime($date));
  
  results in: "1999-11-30"

strtotime的结果是943920000,这大约是Unix纪元(测量时间的基础)到1999-11-30之间的秒数。

当我们尝试预纪元时间(包括" 0000-00-00 00:00:00")时,`mktime(),localtime(),strtotime()上均存在一个已记录的mysql错误,所有错误均返回该奇数值。关于链接线程是否存在错误,存在一些争论:

Since the time stamp is started from 1970, I don't think it supposed to
  work in anyways.

以下是我用于将上述日期时间转换为时间戳以进行比较等的函数,对于超过" 0000-00-00 00:00:00"的日期,这可能对我们有用

/**
 * Converts strings of the format "YYYY-MM-DD HH:MM:SS" into php dates
 */
function convert_date_string($date_string)
{
    list($date, $time) = explode(" ", $date_string);
    list($hours, $minutes, $seconds) = explode(":", $time);
    list($year, $month, $day) = explode("-", $date);
    return mktime($hours, $minutes, $seconds, $month, $day, $year);
}

来自php.net

<?php
function isValidDateTime($dateTime)
{
    if (preg_match("/^(\d{4})-(\d{2})-(\d{2}) ([01][0-9]|2[0-3]):([0-5][0-9]):([0-5][0-9])$/", $dateTime, $matches)) {
        if (checkdate($matches[2], $matches[3], $matches[1])) {
            return true;
        }
    }

    return false;
}
?>

当我们超出范围时,不要期望获得连贯的结果:

cf strtotime

cf Gnu Calendar-date-items.html

"For numeric months, the ISO 8601
  format ‘year-month-day’ is allowed,
  where year is any positive number,
  month is a number between 01
  and 12, and day is a
  number between 01 and 31. A
  leading zero must be present if a
  number is less than ten."

因此," 0000-00-00"给出的结果很奇怪,这是合乎逻辑的!

"Additionally, not all
  platforms support negative timestamps,
  therefore your date range may be
  limited to no earlier than the Unix
  epoch. This means that e.g.
  %e, %T, %R and %D (there might be
  more) and dates prior to Jan
  1, 1970 will not work on Windows, some
  Linux distributions, and a few other
  operating systems."

cf strftime

请改用checkdate函数(更强大):

month:
      The month is between 1 and 12 inclusive.
  
  day:
      The day is within the allowed number of days for the given
  month. Leap year s are taken
  into consideration.
  
  year:
      The year is between 1 and 32767 inclusive.

如果我们只想处理没有mysql日期字段的时间的日期转换,则可以像我一样修改此出色的代码。
在不执行此功能的PHP版本上,每次都会得到" 0000-00-00"。恼人的。

function ConvertDateString ($DateString)
{
    list($year, $month, $day) = explode("-", $DateString);
    return date ("Y-m-d, mktime (0, 0, 0, $month, $day, $year));
}