Есть ли способ проверить, действительны ли дата / время, как вы думаете, это легко проверить:
$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",
Хм? я пошел от 0000-00-00 до 1999-11-30 ???
Я знаю, что могу провести сравнение, чтобы увидеть, совпадает ли дата одного из этих значений с датой, которая у меня есть, но это не очень надежный способ проверки. Есть ли хороший способ проверить, действительна ли у меня дата? У кого-нибудь есть хорошая функция, чтобы проверить это?
Редактировать: Люди спрашивают, чем я занимаюсь: Запуск PHP 5.2.5 (cli) (построено: 23 июля 2008 г., 11:32:27) на Linux localhost 2.6.18-53.1.14.el5 # 1 SMP среда 5 марта 11:36:49 EST 2008 i686 i686 i386 GNU / Linux
strtotime ("0000-00-00 00:00:00") возвращает ЛОЖЬ в 32-битной системе. strtotime ("0000-00-00 00:00:00") возвращает -62169955200 в 64-битной системе.






echo date('Y-m-d', strtotime($date));
results in: "1999-11-30"
Результат strtotime - 943920000 - это количество секунд, примерно, между Эпоха Unix (база, от которой отсчитывается время) до 1999-11-30.
На mktime(), localtime(), strtotime() есть задокументированный ошибка mysql, который возвращает это нечетное значение, когда вы пробуете время до начала эпохи (включая «0000-00-00 00:00:00»). В связанном потоке ведутся споры о том, действительно ли это ошибка:
Since the time stamp is started from 1970, I don't think it supposed to work in anyways.
Ниже приведена функция, которую я использую для преобразования dateTimes, например, выше, в метку времени для сравнения и т. д., Которая может быть вам полезна для дат после "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);
}
Я пробовал дату ('Y-m-d', convert_date_string ('0000-00-00 00:00:00')), но все еще дает дату 1999 года
Нашел отчет об ошибке PHP о странном поведении функций, основанных на времени, в PHP для значения 0000-00 ... В этой ветке ведутся споры о том, действительно ли это ошибка, как будто люди когда-нибудь захотят вычислить дату до 1970 года!
От 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-элементы.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
Вместо этого используйте функцию контрольная дата (более надежная):
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));
}
Эта версия допускает, чтобы поле было пустым, имеет даты в формате мм / дд / гг или мм / дд / гггг, позволяет использовать однозначные часы, добавляет необязательные am / pm и исправляет некоторые незначительные ошибки в сопоставлении времени.
По-прежнему допускаются некоторые патологические времена, такие как «23:14 утра».
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;
}
<?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;
}
?>
Это не работает с некоторыми крайними случаями, такими как 31 февраля или 31 апреля. Например, date («Y-m-d», strtotime («31.2.2012»)) приводит к «2012-03-02», который проходит проверку контрольной даты, даже если пользователь не ввел действительную дату.
Я просто изменил ответ Мартина выше, который будет проверять любой тип даты и возвращать в желаемом формате.
Просто измените формат, отредактировав приведенную ниже строку скрипта. 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" ;
}
}
?>
<?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
это будет работать для дат, которые "недавние", но если у меня есть дата в начале девяноста, он всегда будет возвращать false
@SeanDowney отредактировал, что должно вернуть ИСТИНА для вашего «свидания в начале девяностых».
Как упоминалось здесь: 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.
И, как показано в нескольких тестах, откат назад является ожидаемым поведением, хотя и немного тревожным:
>> 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'
Я использовал следующий код для проверки дат, поступающих из приложений 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);
}
Попробуйте это: php.net/manual/en/function.checkdate.php