如何在PHP中创建一个好的“日期选择器”?

如何在PHP中创建一个好的“日期选择器”?,php,javascript,datetime,datepicker,Php,Javascript,Datetime,Datepicker,我正在用MySQL和PHP做一些实验,我对创建一个好的日期选择器很好奇,例如,选择2010-11-11的日期今天的日期 我想在我的MySQL数据库中存储有效的DATETIME值,并且我想要一个PHP页面来提供年、月和日的滚动列表,例如2010-11-11,以避免强制用户在表单中手动写入日期,然后进行检查 我的问题是,假设用户选择的日期是2010-11-31,但它并不存在;如何创建简单的滚动列表以便进行动态调整?也就是说,用户首先选择年份,然后选择月份,最后选择动态更改以适应给定月份实际天数的日期

我正在用MySQL和PHP做一些实验,我对创建一个好的日期选择器很好奇,例如,选择2010-11-11的日期今天的日期

我想在我的MySQL数据库中存储有效的DATETIME值,并且我想要一个PHP页面来提供年、月和日的滚动列表,例如2010-11-11,以避免强制用户在表单中手动写入日期,然后进行检查

我的问题是,假设用户选择的日期是2010-11-31,但它并不存在;如何创建简单的滚动列表以便进行动态调整?也就是说,用户首先选择年份,然后选择月份,最后选择动态更改以适应给定月份实际天数的日期。希望闰年也能得到照顾。在全部选中并按“提交”后,脚本将向数据库提交格式正确的日期时间值,例如YYYY-MM-DD或YYYYMMDD

据我所知,DATETIME类型作为标准是严格的,这意味着服务器将跟踪无效日期,这应该很容易进行错误检查。但是我想通过做我上面描述的事情来避免这种情况


您认为我所描述的“解决方案”仅使用PHP和MySQL就很容易实现吗?或者我需要一些其他的东西,比如AJAX/JavaScript、JQuery等来管理它吗?任何建议和指针都是非常受欢迎的,尤其是对同一问题的替代方法,可能更容易实现。提前谢谢

现在已经有很多基于JavaScript的日历小部件了。如果你不是为了学习而这样做,就没有理由重新发明轮子

当然,服务器端验证仍然是强制性的,但这些小部件将使用户无法在正常情况下选择无效日期

例如


现在已经有很多基于JavaScript的日历小部件了。如果你不是为了学习而这样做,就没有理由重新发明轮子

当然,服务器端验证仍然是强制性的,但这些小部件将使用户无法在正常情况下选择无效日期

例如


jQuery和另一个JavaScript框架可以完成这项工作。

jQuery和另一个JavaScript框架可以完成这项工作。

你不能。为此,您需要一个客户端解决方案


PHP处理数据处理,因此您将有一个支持JavaScript的日期选择器,用户在其中选择日期,然后您将让PHP在提交表单时将所选日期保存在数据库中。

您不能。为此,您需要一个客户端解决方案


PHP处理数据处理,因此您将拥有一个支持JavaScript的日期选择器,用户在其中选择日期,然后您将让PHP在提交表单时将所选日期保存在数据库中。

您试图解决客户端问题,而服务器端则是imho,尽管服务器端永远不能忽略验证

但是无效日期,就像你的例子,实际上并不是一个问题,因为你可以使用哪个日期吃得最好。当然,在这种情况下,它将计算到12月1日,但无论如何都是一个有效日期。您可以使用strotime的输出,以数据库友好的方式对其进行格式化

进一步说,如果您想确保输入的日期不仅在形式上有效,还可以使用strotime对其进行解析,使用发送到脚本的格式中的日期对其进行格式化,并比较两个字符串。如果不完全相同,你就会知道出了什么问题

根据你的例子:

$datePosted = '2010-11-31';    
$fromClient = date('Y-m-d', strtotime($datePosted));

// $fromClient == '2010-12-01' 

if (strcmp($datePosted, $fromClient) != 0) {
  // Invalid date posted
} else {
  // All is well on the western front
}

您可能还对较新版本的PHP提供的类感兴趣。

您试图在服务器端解决客户端问题,尽管服务器端永远不能忽略验证

但是无效日期,就像你的例子,实际上并不是一个问题,因为你可以使用哪个日期吃得最好。当然,在这种情况下,它将计算到12月1日,但无论如何都是一个有效日期。您可以使用strotime的输出,以数据库友好的方式对其进行格式化

进一步说,如果您想确保输入的日期不仅在形式上有效,还可以使用strotime对其进行解析,使用发送到脚本的格式中的日期对其进行格式化,并比较两个字符串。如果不完全相同,你就会知道出了什么问题

根据你的例子:

$datePosted = '2010-11-31';    
$fromClient = date('Y-m-d', strtotime($datePosted));

// $fromClient == '2010-12-01' 

if (strcmp($datePosted, $fromClient) != 0) {
  // Invalid date posted
} else {
  // All is well on the western front
}

您可能还对新版本的PHP提供的类感兴趣。

应该不需要Ajax。Ajax调用服务器,但是服务器不知道比客户端更多的有效日期,所以这一切都可以用javascript完成。如果您已经在使用jQuery,请使用jQuery插件,但不要为了这个目的而加载整个jQuery库:这太过分了。有很多轻量级的日期选择器。您所要做的就是重新加载s时的可用天数 omeone更改月份/年份记住二月:您也需要在年度更改时重新加载

我们采用了一种方法,其中包括一周中的一天的名称和日期:

function OnMonthYearChange(name) {
    var week = ['Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday'];
    var year = document.getElementById(name + '-year');
    var mon  = document.getElementById(name + '-mon');
    var mday = document.getElementById(name + '-mday');
    if ((mon.value  == '') || (year.value == '')) {
        return;
    }

    var date = new Date();
    date.setYear(year.value);
    date.setMonth(mon.value);
    var l = getDaysInMonth(year.value, mon.value);
    var day = mday.value;

    clearSelect(mday);
    var w = 0;
    for (i = 0; i < l; i++) {
        date.setFullYear(year.value, mon.value - 1, i + 1);
        w = date.getDay();
        var o = document.createElement('option');
        o.value = getLeadingZero(i + 1);
        o.text = o.value + ' - ' + week[w];
        //alert(o.text);
        if (i == (day - 1)) o.selected = true;
        if (app.IsIE) {
            mday.add(o);
        } else {
            mday.options.add(o);
        }
    }
}
function getDaysInMonth(year, month) {
    var m = [31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31];
    if (month != 2) return m[month - 1];
    if (year % 4 != 0) return m[1];
    if (year % 100 == 0 && year % 400 != 0) return m[1];
    return m[1] + 1;
}
function clearSelect(e) {
    var first = e.options[0].innerHTML;
    if (first) {
        // Form does not allow selection of a blank date. Drop all existing options.
        e.options.length = 0;
    } else {
        // Form allows selection of a blank date. First option is blank. Keep it.
        e.options.length = 1;
    }
}
function getLeadingZero(n) {
    if (n < 10) n = '0' + n;
    return n;
}
有关弹出日历的不同方法,请参见。可以将两者集成,将弹出日历的结果反馈回选择框


记住,人们可以禁用javascript并在客户端执行各种奇怪的操作,因此服务器端验证仍然很重要。

应该不需要Ajax。Ajax调用服务器,但是服务器不知道比客户端更多的有效日期,所以这一切都可以用javascript完成。如果您已经在使用jQuery,请使用jQuery插件,但不要为了这个目的而加载整个jQuery库:这太过分了。有很多轻量级的日期选择器。你所要做的就是重新加载有人更改月份/年份时的可用天数记住二月:你也需要在年度更改时重新加载

我们采用了一种方法,其中包括一周中的一天的名称和日期:

function OnMonthYearChange(name) {
    var week = ['Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday'];
    var year = document.getElementById(name + '-year');
    var mon  = document.getElementById(name + '-mon');
    var mday = document.getElementById(name + '-mday');
    if ((mon.value  == '') || (year.value == '')) {
        return;
    }

    var date = new Date();
    date.setYear(year.value);
    date.setMonth(mon.value);
    var l = getDaysInMonth(year.value, mon.value);
    var day = mday.value;

    clearSelect(mday);
    var w = 0;
    for (i = 0; i < l; i++) {
        date.setFullYear(year.value, mon.value - 1, i + 1);
        w = date.getDay();
        var o = document.createElement('option');
        o.value = getLeadingZero(i + 1);
        o.text = o.value + ' - ' + week[w];
        //alert(o.text);
        if (i == (day - 1)) o.selected = true;
        if (app.IsIE) {
            mday.add(o);
        } else {
            mday.options.add(o);
        }
    }
}
function getDaysInMonth(year, month) {
    var m = [31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31];
    if (month != 2) return m[month - 1];
    if (year % 4 != 0) return m[1];
    if (year % 100 == 0 && year % 400 != 0) return m[1];
    return m[1] + 1;
}
function clearSelect(e) {
    var first = e.options[0].innerHTML;
    if (first) {
        // Form does not allow selection of a blank date. Drop all existing options.
        e.options.length = 0;
    } else {
        // Form allows selection of a blank date. First option is blank. Keep it.
        e.options.length = 1;
    }
}
function getLeadingZero(n) {
    if (n < 10) n = '0' + n;
    return n;
}
有关弹出日历的不同方法,请参见。可以将两者集成,将弹出日历的结果反馈回选择框


请记住,人们可以禁用javascript并在客户端执行各种奇怪的操作,因此服务器端验证仍然很重要。

正如Pekka所说,您不能使用“just PHP”进行日期选取,因为PHP“just”在服务器上,而您的用户在浏览器/客户端上。正如Pekka所说,您不能使用“just PHP”进行日期选取,因为PHP“只是”在服务器上,而您的用户在浏览器/客户端上。