Datepicker是jQuery UI套件里最常用的控件之一,但默认输出是英文界面,星期栏显示Su Mo Tu,按钮是Done和Prev,放在中文项目里观感非常割裂。更麻烦的是订票、报表这类场景往往需要开始日期和结束日期两个控件联动,用户选了开始日期后,结束日期不能早于它。这篇文章就围绕汉化和联动这两个需求,把实现思路和完整代码讲清楚。

一、Datepicker汉化的两种实现方式
汉化的核心是给Datepicker提供一个区域设置对象。jQuery UI官方在i18n目录下提供了各语言包,其中jquery.ui.datepicker-zh-CN.js就是简体中文包,引入后调用$.datepicker.setDefaults($.datepicker.regional['zh-CN'])即可全局生效。这种方式最省事,适合整个项目统一中文环境的情况。
如果不想额外引入文件,或者需要针对个别控件定制文案,也可以直接在初始化时传参。Datepicker的可配置项相当丰富,monthNames控制完整月份名,dayNamesMin控制星期栏缩写,prevText和nextText是翻页按钮提示文字,currentText和closeText对应今天和关闭按钮。下面是一个完整的配置示例:
$(function () {
$.datepicker.regional['zh-CN'] = {
closeText: '关闭',
prevText: '<上月',
nextText: '下月>',
currentText: '今天',
monthNames: ['一月', '二月', '三月', '四月', '五月', '六月',
'七月', '八月', '九月', '十月', '十一月', '十二月'],
monthNamesShort: ['一', '二', '三', '四', '五', '六',
'七', '八', '九', '十', '十一', '十二'],
dayNames: ['星期日', '星期一', '星期二', '星期三', '星期四', '星期五', '星期六'],
dayNamesShort: ['周日', '周一', '周二', '周三', '周四', '周五', '周六'],
dayNamesMin: ['日', '一', '二', '三', '四', '五', '六'],
weekHeader: '周',
dateFormat: 'yy-mm-dd',
firstDay: 1,
isRTL: false,
showMonthAfterYear: true,
yearSuffix: '年'
};
$.datepicker.setDefaults($.datepicker.regional['zh-CN']);
});这里有两个容易忽略的细节。firstDay设为1表示每周从周一开始,更符合国内习惯,默认值0是周日开头。showMonthAfterYear设为true后标题栏显示为2024年11月这种格式,配合yearSuffix加上年字,整体观感才像原生中文控件。日期格式建议用yy-mm-dd,Datepicker中yy会输出四位年份,这点和原生JavaScript的格式化习惯不同,写成yyyy反而会出问题。
二、日期范围联动的实现原理
联动的本质是两个控件共享约束条件:结束日期的minDate不能早于开始日期,开始日期的maxDate不能晚于结束日期。Datepicker在每次用户选中日期时会触发onSelect回调,我们就在这个回调里动态修改另一个控件的边界值。
具体做法是:开始日期控件选中后,读取选中的日期字符串,通过$('#endDate').datepicker('option', 'minDate', dateStr)把结束日期的最小可选值设为该日期;反过来结束日期选中后更新开始日期的maxDate。Datepicker接受字符串、Date对象和相对偏移三种参数形式,直接传yyyy-mm-dd格式的字符串即可被正确解析。完整代码如下:
$(function () {
var startDate = $('#startDate');
var endDate = $('#endDate');
startDate.datepicker({
dateFormat: 'yy-mm-dd',
minDate: 0, // 开始日期不能选今天之前
onSelect: function (dateStr) {
// 开始日期变化后,限制结束日期的下限
endDate.datepicker('option', 'minDate', dateStr);
}
});
endDate.datepicker({
dateFormat: 'yy-mm-dd',
onSelect: function (dateStr) {
// 结束日期变化后,限制开始日期的上限
startDate.datepicker('option', 'maxDate', dateStr);
}
});
});这段代码实现了基本的双向约束,但实际项目里往往还要考虑清空的场景。用户手动删掉输入框内容后,另一个控件的限制却还残留着,会导致明明可以自由选择却选不了。解决办法是监听输入框的change事件,发现值为空时通过datepicker('option', 'minDate', null)把边界重置。如果业务上还要求起止间隔不超过30天,可以在onSelect里同时设置对侧的maxDate或minDate为当前日期加偏移,例如endDate.datepicker('option', 'maxDate', '+30d')。
三、增强体验:双日历面板与常用配置
订票类页面通常希望一次展示两个月的日历,减少翻页次数,这靠numberOfMonths实现,可以传数字也可以传数组如[2, 1]表示两行一列。再加上showButtonPanel: true显示今天和关闭按钮,changeMonth和changeYear允许直接下拉选择年月,查询历史日期时会方便很多。整合后的配置示例如下:
$('#startDate').datepicker({
dateFormat: 'yy-mm-dd',
numberOfMonths: 2,
showButtonPanel: true,
changeMonth: true,
changeYear: true,
yearRange: '2020:2030',
minDate: 0,
onSelect: function (dateStr) {
$('#endDate').datepicker('option', 'minDate', dateStr);
}
});需要注意yearRange只是下拉框的显示范围,不会限制可选日期,真正的日期限制仍然要靠minDate和maxDate。另外下拉年份跨度设得太大也不好,用户滚动体验差,一般控制在前后十年以内比较合适。
四、常见踩坑点排查
第一个坑是语言包引入顺序。jquery.ui.datepicker-zh-CN.js必须在jquery-ui主文件之后引入,否则$.datepicker.regional对象还不存在,脚本会直接报错或者汉化不生效。第二个坑是重复调用setDefaults被后执行的英文配置覆盖,常见于多个页面脚本合并加载时,排查时可以在控制台打印$.datepicker.regional['zh-CN']确认配置是否存在。
第三个坑是onSelect回调绑定时机。如果用datepicker('option')的方式修改配置后,onSelect仍指向旧函数,可能造成联动逻辑失效,建议统一在初始化时配置好。第四个坑和输入体验有关:默认情况下用户可以手动在输入框里敲任意日期绕过限制,联动约束只在控件面板里生效,提交前务必在服务端再校验一次起止关系,前端校验可以用getDate方法取到Date对象后比较时间戳:
function validateRange() {
var s = $('#startDate').datepicker('getDate');
var e = $('#endDate').datepicker('getDate');
if (s && e && e.getTime() < s.getTime()) {
alert('结束日期不能早于开始日期');
return false;
}
return true;
}最后提一下与后端交互的格式问题。控件里显示中文如2024年11月5日没问题,但提交给后端时应统一使用ISO格式,可以在altField配合altFormat的方式,让输入框展示友好格式的同时,隐藏域里存一份标准的yy-mm-dd值,展示与数据各司其职,后续维护也清晰。
jQuery UI Datepicker日期控件汉化日期范围选择修改时间:2026-09-15 21:34:40