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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/141315/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-24 21:39:20  来源:igfitidea点击:

php check for a valid date, weird date conversions

phpdatetimestrtotime

提问by SeanDowney

Is there a way to check to see if a date/time is valid you would think these would be easy to check:

有没有办法检查日期/时间是否有效,您会认为这些很容易检查:

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

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

what really gets me is this:

真正让我着迷的是:

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

results in: "1999-11-30",

结果:“1999-11-30”,

huh? i went from 0000-00-00 to 1999-11-30 ???

嗯?我从 0000-00-00 到 1999-11-30 ???

I know i could do comparison to see if the date is either of those values is equal to the date i have but it isn't a very robust way to check. Is there a good way to check to see if i have a valid date? Anyone have a good function to check this?

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

Edit: People are asking what i'm running: Running PHP 5.2.5 (cli) (built: Jul 23 2008 11:32:27) on Linux localhost 2.6.18-53.1.14.el5 #1 SMP Wed Mar 5 11:36:49 EST 2008 i686 i686 i386 GNU/Linux

编辑:人们问我在运行什么:在 Linux localhost 2.6.18-53.1.14.el5 #1 SMP Wed Mar 5 11 上运行 PHP 5.2.5 (cli)(构建:2008 年 7 月 23 日 11:32:27) :36:49 EST 2008 i686 i686 i386 GNU/Linux

回答by mk.

From php.net

来自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;
}
?>

回答by Izkata

As mentioned here: https://bugs.php.net/bug.php?id=45647

正如这里提到的:https: //bugs.php.net/bug.php?id=45647

There is no bug here, 00-00-00 means 2000-00-00, which is 1999-12-00, which is 1999-11-30. No bug, perfectly normal.

这里没有bug,00-00-00表示2000-00-00,也就是1999-12-00,也就是1999-11-30。没有错误,完全正常。

And as shown with a few tests, rolling backwards is expected behavior, if a little unsettling:

正如一些测试所示,如果有点令人不安,向后滚动是预期的行为:

>> date('Y-m-d', strtotime('2012-03-00'))
string: '2012-02-29'
>> date('Y-m-d', strtotime('2012-02-00'))
string: '2012-01-31'
>> date('Y-m-d', strtotime('2012-01-00'))
string: '2011-12-31'
>> date('Y-m-d', strtotime('2012-00-00'))
string: '2011-11-30'

回答by ConroyP

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

results in: "1999-11-30"

echo date('Ym-d', strtotime($date));

结果:“1999-11-30”

The result of strtotimeis 943920000 - this is the number of seconds, roughly, between the Unix epoch(base from which time is measured) to 1999-11-30.

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

There is a documented mysql bugon mktime(), localtime(), strtotime()all returning this odd value when you try a pre-epoch time (including "0000-00-00 00:00:00"). There's some debate on the linked thread as to whether this is actually a bug:

有一个文件mysql的错误mktime(), localtime(), strtotime(),当你尝试前历元时刻都返回这个奇怪的值(包括“0000-00-00 00:00:00”)。关于链接线程是否真的是一个错误存在一些争论:

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

由于时间戳是从 1970 年开始的,我认为它无论如何都不应该起作用。

Below is a function that I use for converting dateTimes such as the above to a timestamp for comparisons, etc, which may be of some use to you, for dates beyond "0000-00-00 00:00:00"

以下是我用于将上述日期时间转换为时间戳以进行比较等的函数,对于超出“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);
}

回答by user22960

Don't expect coherent results when you're out of range:

当您超出范围时,不要期望一致的结果:

cf strtotime

CF的strtotime

cf Gnu Calendar-date-items.html

参见Gnu 日历日期项目.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."

“对于数字月份,允许使用 ISO 8601 格式 'year-month-day',其中 year 是任何正数, month 是 01 和 12 之间的数字day 是 01 和 31 之间的数字。前导零必须是如果数字小于十,则出现。”

So '0000-00-00' gives weird results, that's logical!

所以'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."

“此外,并非所有平台都支持负时间戳,因此您的日期范围可能被限制为不早于 Unix 纪元。这意味着例如 %e、%T、%R 和 %D(可能有更多)和之前的日期1970 年 1 月 1 日将不适用于 Windows、某些 Linux 发行版和一些其他操作系统。”

cf strftime

参考strftime



Use checkdatefunction instead (more robust):

改用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.

月份:月份介于 1 和 12 之间(包括 1 和 12)

day:该天在给定月份的允许天数内。闰年被考虑在内。

年份:年份介于 1 和 32767 之间(包括 1 和 32767)

回答by dave

If you just want to handle a date conversion without the time for a mysql date field, you can modify this great code as I did. On my version of PHP without performing this function I get "0000-00-00" every time. Annoying.

如果您只想处理日期转换而没有 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));
}

回答by asupynuk

This version allows for the field to be empty, has dates in mm/dd/yy or mm/dd/yyyy format, allow for single digit hours, adds optional am/pm, and corrects some subtle flaws in the time match.

此版本允许字段为空,日期为 mm/dd/yy 或 mm/dd/yyyy 格式,允许单位数小时,添加可选的 am/pm,并更正时间匹配中的一些细微缺陷。

Still allows some pathological times like '23:14 AM'.

仍然允许一些病理时间,如“23:14 AM”。

function isValidDateTime($dateTime) {
    if (trim($dateTime) == '') {
        return true;
    }
    if (preg_match('/^(\d{1,2})\/(\d{1,2})\/(\d{2,4})(\s+(([01]?[0-9])|(2[0-3]))(:[0-5][0-9]){0,2}(\s+(am|pm))?)?$/i', $dateTime, $matches)) {
        list($all,$mm,$dd,$year) = $matches;
        if ($year <= 99) {
            $year += 2000;
        }
        return checkdate($mm, $dd, $year);
    }
    return false;
}

回答by asupynuk

I have been just changing the martin answer above, which will validate any type of date and return in the format you like.

我刚刚更改了上面的 martin 答案,它将验证任何类型的日期并以您喜欢的格式返回。

Just change the format by editing below line of script strftime("10-10-2012", strtotime($dt));

只需通过编辑下面的脚本 strftime("10-10-2012", strtotime($dt)); 行来更改格式;

<?php
echo is_date("13/04/10");

function is_date( $str ) {
    $flag = strpos($str, '/');

    if(intval($flag)<=0){
        $stamp = strtotime( $str );
    } else {
        list($d, $m, $y) = explode('/', $str);    
        $stamp = strtotime("$d-$m-$y");
    } 
    //var_dump($stamp) ;

    if (!is_numeric($stamp)) {
        //echo "ho" ;
        return "not a date" ;        
    }

    $month = date( 'n', $stamp ); // use n to get date in correct format
    $day   = date( 'd', $stamp );
    $year  = date( 'Y', $stamp );

    if (checkdate($month, $day, $year)) {
        $dt = "$year-$month-$day" ;
        return strftime("%d-%b-%Y", strtotime($dt));
        //return TRUE;
    } else {
        return "not a date" ;
    }
}
?>

回答by Josue

<?php
function is_valid_date($user_date=false, $valid_date = "1900-01-01") {
    $user_date = date("Y-m-d H:i:s",strtotime($user_date));
    return strtotime($user_date) >= strtotime($valid_date) ? true : false;
}

echo is_valid_date("00-00-00") ? 1 : 0;    // return 0

echo is_valid_date("3/5/2011") ? 1 : 0;    // return 1

回答by eli

I have used the following code to validate dates coming from ExtJS applications.

我使用以下代码验证来自 ExtJS 应用程序的日期。

function check_sql_date_format($date) {
    $date = substr($date, 0, 10);
    list($year, $month, $day) = explode('-', $date);
    if (!is_numeric($year) || !is_numeric($month) || !is_numeric($day)) {
        return false;
    }
    return checkdate($month, $day, $year);
}

回答by martin

<?php

function is_date( $str ) {
    $stamp = strtotime( $str );

    if (!is_numeric($stamp)) {
        return FALSE;
    }
    $month = date( 'm', $stamp );
    $day   = date( 'd', $stamp );
    $year  = date( 'Y', $stamp );

    if (checkdate($month, $day, $year)) {
        return TRUE;
    }
    return FALSE;
}
?>