一个简单的生日系统(PHP / MySQL)有问题


Having issues with a simple birthday system (PHP / MySQL)

我正在考虑当数据库中存在冲突的日期系统时会发生什么情况,当这种情况发生时会导致PHP混乱。例如,如果数据库的一部分包含01/01/2016,但在其他地方包含1/1/2016,那么日期系统似乎就会崩溃。在适当的环境中,我认为它应该是epoch,但在这种情况下,它不是。

下面的代码是混乱的,也许我想太多了。但这是我有的:

    /*
    *
    * Dates ($dob) can appear as followed:
    * 01-30-2016 | 1-30-2016 | 01-01-2016 | 01/30/2016 or any combination
    *
    */
    $chpos = 0;         // Define Character Position Variable
    $replace = false;   // Should we replace the 0 after the first dash?
    // If the date uses this format: 01/02/2016 then replace the / with - so it looks like 01-02-2016
    $dob = preg_replace('/'s+/', '-', $dob);
    // Let's find out if the dash occurs on the 3rd character or 4th. We do this so we can replace the 0 in 2-02-2016
    // 01-34-6789 *String Array positions* 0-23-5678
    if(substr($dob, 0, 3) == 0 && substr($dob, 0, 0) == 0){
        $chpos = 3;
        $replace == true;
    } else if (substr($dob, 0, 0) != 0 && substr($dob, 0, 2) == 0){
        $chpos = 2;
        $replace == true;
    } else {
        $replace == false;
    }
    // Let's replace the 0 after the first dash if necessary
    if($replace == true){
        $dob = substr_replace($dob, '', $chpos);
    }
    // Let's replace the 0 from the beginning if necessary
    if(substr($dob, 0, 1 ) == 0){
       $dob = substr( $dob, 1 );
    }
    // Let's convert it to a usable date object       
    $birthday = new DateTime($dob);
    // Now let's compare the time from now to when the birthdate happened
    $interval = $birthday->diff(new DateTime);
    // Return the data over
    return $interval->y;

代码的问题与何时替换左边的0有关。我可以发誓代码应该可以工作,但也许我打错了,只是看不到它?我不知道,但根本不管用。消息是:

 Uncaught exception 'Exception' with message 'DateTime::__construct(): Failed to parse time string (2-17-1994) at position 0 (2): Unexpected character'

引用的行是:$birthday = new DateTime($dob);

我的问题是:

  • 为什么日期系统有前导零时会中断?

  • 为什么解析日期这么复杂?

  • 我错过了什么还是应该这么困难?

  • 我想太多了吗?

感谢您的宝贵时间!

忽略数据清理问题(任务不应该以不同的格式进入数据库;Unix时间戳会是更好的选择)…

$timedob = strtotime($dob);
$birthday = date('Y-m-d',$timedob);

strtotime接受任意字符串并将其转换为Unix时间戳。date函数然后将unix时间戳转换为所需的输出格式。

注意strtotime对输入的解释如下:如果月、日、年以斜杠"/"分隔,则假定日期格式为美式m/d/y。如果看到连字符或句点(-或。),则假定日期为欧洲d-m-y格式。

在php中解析日期字符串非常容易,使用strtottime等函数,它会达到非常长的长度,以最好地解释字符串。http://php.net/manual/en/function.strtotime.php

你遇到的问题是,你应该在数据库中存储日期作为数据库日期或日期时间格式(或任何等效的有你的数据库)。在尝试将它们输入数据库之前应该进行验证,并测试任何数据库写入不会因为格式错误的日期结构而被拒绝。在转换为输出日期时,还应该进行进一步的验证。

自从我不得不像你在这里做的那样手动操作日期字符串以来,已经有很长一段时间了,当然没有必要这样做。特别是因为日期选择器是如此普遍,也将格式日期浏览器端通过js发送之前。(当然,这并不能消除对服务器端验证的需要。)

如果我是你,我会写一个简短的脚本,将你所有的日期转换为数据库的合适日期格式,并将该数据库列的格式更改为日期格式。然后在您的应用程序中将字符串作为日期写入数据库的任何地方进行地址处理。在一个结构良好的应用程序中,这应该只在一个模型函数中完成,所以不应该花费太长时间。

正确执行此操作的最后一个好处是,您现在可以轻松生成报告或查询结果,例如在某某日期之前或两个日期之间或星期二等发生的每个事件。