php للتحقق من تاريخ صالح، وتحويلات تاريخ غريبة

StackOverflow https://stackoverflow.com/questions/141315

  •  02-07-2019
  •  | 
  •  

سؤال

هل هناك طريقة للتحقق لمعرفة ما إذا كان التاريخ/الوقت صالحًا وتعتقد أنه سيكون من السهل التحقق منه:

$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)); 

النتائج في:"30/11/1999"،

هاه؟ذهبت من 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 بتوقيت شرق الولايات المتحدة 2008 i686 i686 i386 GNU/Linux

هل كانت مفيدة؟

المحلول

من 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;
}
?>

نصائح أخرى

كما ذكر هنا : https://bugs.php.net/bug.php?id=45647

لا يوجد أي خطأ هنا ، 00-00-00 يعني 2000-00-00 ، وهو 1999-12-00 ، وهو 1999-11-30.لا يوجد خطأ، طبيعي تماما.

وكما هو موضح في بعض الاختبارات، يعتبر التراجع سلوكًا متوقعًا، وإن كان مقلقًا بعض الشيء:

>> 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'

تاريخ الصدى('Y-m-d', strtotime($date));

النتائج في:"30/11/1999"

نتائج strtotime هو 943920000 - هذا هو عدد الثواني تقريبًا بين عصر يونكس (القاعدة التي يتم قياس الوقت منها) إلى 30/11/1999.

هناك موثقة علة الخلية على mktime(), localtime(), strtotime() جميعها تُرجع هذه القيمة الفردية عند تجربة وقت ما قبل العصر (بما في ذلك "0000-00-00 00:00:00").هناك بعض الجدل حول الموضوع المرتبط حول ما إذا كان هذا خطأ بالفعل:

منذ بدء الطوابع الزمنية من عام 1970 ، لا أعتقد أنه من المفترض أن تعمل على أي حال.

يوجد أدناه وظيفة أستخدمها لتحويل 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);
}

لا تتوقع نتائج متماسكة عندما تكون خارج النطاق:

راجع com.strtotime

راجع عناصر تاريخ التقويم Gnu.لغة البرمجة

"للأشهر الرقمية ، يُسمح بتنسيق ISO 8601" يوم الشهر "، حيث يكون العام أي رقم إيجابي ، الشهر هو رقم بين 01 و 12, ، و اليوم هو رقم بين 01 و 31.يجب أن يكون الصفر الرائد موجودًا إذا كان الرقم أقل من عشرة. "

لذا فإن "0000-00-00" يعطي نتائج غريبة، وهذا منطقي!


"بالإضافة إلى ذلك، لا تدعم جميع المنصات الطوابع الزمنية السلبية ، وبالتالي قد يقتصر نطاق تاريخك على عدم وجود عصر UNIX في وقت سابق.وهذا يعني أن على سبيل المثال.٪ e ، ٪ t ، ٪ r و ٪ d (قد يكون هناك المزيد) و تواريخ قبل 1 يناير 1970 لن تعمل على Windows وبعض توزيعات Linux وبعض أنظمة التشغيل الأخرى."

راجع com.strftime


يستخدم راجع التاريخ وظيفة بدلاً من ذلك (أكثر قوة):

شهر:ال الشهر بين 1 و 12 شاملاً.

يوم:اليوم هو ضمن عدد الأيام المسموح بها للشهر المحدد.تؤخذ سنة قفزة في الاعتبار.

سنة:ال السنة تتراوح بين 1 و 32767 ضمناً.

يسمح هذا الإصدار بأن يكون الحقل فارغًا، وأن يحتوي على تواريخ بتنسيق mm/dd/yy أو mm/dd/yyyy، ويسمح بساعات مكونة من رقم واحد، ويضيف صباحًا/مساءً اختياريًا، ويصحح بعض العيوب الدقيقة في مطابقة الوقت.

لا يزال يسمح ببعض الأوقات المرضية مثل "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;
}

إذا كنت تريد فقط التعامل مع تحويل التاريخ دون تخصيص الوقت لحقل التاريخ في 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));
}
<?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

لقد قمت للتو بتغيير إجابة مارتن أعلاه، والتي ستتحقق من صحة أي نوع من التاريخ وتعود بالتنسيق الذي تريده.

ما عليك سوى تغيير التنسيق عن طريق التحرير أدناه سطر Script 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" ;
    }
}
?>

لقد استخدمت الكود التالي للتحقق من صحة التواريخ الواردة من تطبيقات 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

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;
}
?>
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top