如何让jQuery Datepicker基于商家本地时间设置配送截止时间?
基于商家本地时间设置jQuery Datepicker配送日期限制
我在花店网站使用jQuery Datepicker,原本通过以下全局设置实现上午11点后无法选择当日作为配送日期:
minDate: new Date().getHours() >= 11 ? 1 : 0, // 最早可选日期,null表示无限制 maxDate: null, // 最晚可选日期,null表示无限制
但该逻辑基于用户本地时间判断。我们位于加州,当纽约用户当地时间到11点时,加州仅为8点,此时日期选择器会提前锁定当日,不符合商家的配送规则。我需要强制日期选择器基于商家(加州)本地时间运行,而非用户时间。当前日期选择器代码如下:
$(function() { $("#attrib-11-0").attr( 'readOnly' , 'true' ); var array = ["2023-02-13","2023-02-14","2022-05-06","2022-05-05","2022-04-21","2022-02-11","2022-02-12","2022-02-13","2022-02-14","2022-02-15","2022-02-16","2022-01-03","2021-12-24","2021-12-23","2021-12-22","2021-12-21","2021-12-20","2021-01-09","2021-01-16","2021-01-23","2021-01-30","2020-07-03","2020-07-04","2020-11-28", "2020-11-26","2020-12-05","2020-12-12","2020-12-19","2020-12-21","2020-12-22","2020-12-23","2020-12-24","2020-12-26","2020-12-25","2020-12-28"] var today = new Date(); $("#attrib-11-0").attr( 'readOnly' , 'true' ); $("#attrib-11-0").datepicker({ dateFormat: 'MM dd yy', // minDate: +1, beforeShowDay: function(date) { var string = jQuery.datepicker.formatDate('yy-mm-dd', date); if (contains(array,string)) { return [false, ''] } else { var day = date.getDay(); return [(day != 0 && day != 6), '']; } }, //beforeShowDay: $.datepicker.noWeekends, onSelect: function(dateText, inst) { $('#attrib-11-0').val(dateText); } }); }); function contains(a, obj) { var i = a.length; while (i--) { if (a[i] === obj) { return true; } } return false; }
解决方案:基于商家时区设置minDate
核心思路是获取商家所在的加州太平洋时区时间,而非用户本地时间,以此判断是否锁定当日配送。下面提供两种可行方案:
方案1:后端返回商家当前时间(推荐)
通过后端接口直接返回商家当前的小时数(或完整时间戳),前端用这个值判断minDate,这是最准确的方式,不受用户设备时区影响。
修改后的代码示例:
$(function() { $("#attrib-11-0").attr( 'readOnly' , 'true' ); var array = ["2023-02-13","2023-02-14","2022-05-06","2022-05-05","2022-04-21","2022-02-11","2022-02-12","2022-02-13","2022-02-14","2022-02-15","2022-02-16","2022-01-03","2021-12-24","2021-12-23","2021-12-22","2021-12-21","2021-12-20","2021-01-09","2021-01-16","2021-01-23","2021-01-30","2020-07-03","2020-07-04","2020-11-28", "2020-11-26","2020-12-05","2020-12-12","2020-12-19","2020-12-21","2020-12-22","2020-12-23","2020-12-24","2020-12-26","2020-12-25","2020-12-28"] // 替换为后端接口返回的商家当前小时数 const merchantHour = 8; $("#attrib-11-0").datepicker({ dateFormat: 'MM dd yy', // 根据商家时间设置最早可选日期 minDate: merchantHour >= 11 ? 1 : 0, beforeShowDay: function(date) { var string = jQuery.datepicker.formatDate('yy-mm-dd', date); if (contains(array,string)) { return [false, ''] } else { var day = date.getDay(); return [(day != 0 && day != 6), '']; } }, onSelect: function(dateText, inst) { $('#attrib-11-0').val(dateText); } }); }); function contains(a, obj) { var i = a.length; while (i--) { if (a[i] === obj) { return true; } } return false; }
方案2:前端通过UTC时间计算加州时间(无后端支持时使用)
太平洋时区标准时间为UTC-8,夏令时为UTC-7。可以通过UTC时间转换计算出当前加州时间,需注意夏令时规则(美国夏令时为3月第二个周日至11月第一个周日)。
完整代码示例:
$(function() { $("#attrib-11-0").attr( 'readOnly' , 'true' ); var array = ["2023-02-13","2023-02-14","2022-05-06","2022-05-05","2022-04-21","2022-02-11","2022-02-12","2022-02-13","2022-02-14","2022-02-15","2022-02-16","2022-01-03","2021-12-24","2021-12-23","2021-12-22","2021-12-21","2021-12-20","2021-01-09","2021-01-16","2021-01-23","2021-01-30","2020-07-03","2020-07-04","2020-11-28", "2020-11-26","2020-12-05","2020-12-12","2020-12-19","2020-12-21","2020-12-22","2020-12-23","2020-12-24","2020-12-26","2020-12-25","2020-12-28"] // 获取当前加州时间的小时数 const californiaTime = getCaliforniaTime(); $("#attrib-11-0").datepicker({ dateFormat: 'MM dd yy', minDate: californiaTime.hours >= 11 ? 1 : 0, beforeShowDay: function(date) { var string = jQuery.datepicker.formatDate('yy-mm-dd', date); if (contains(array,string)) { return [false, ''] } else { var day = date.getDay(); return [(day != 0 && day != 6), '']; } }, onSelect: function(dateText, inst) { $('#attrib-11-0').val(dateText); } }); }); function contains(a, obj) { var i = a.length; while (i--) { if (a[i] === obj) { return true; } } return false; } // 计算加州当前时间(含夏令时判断) function getCaliforniaTime() { const now = new Date(); const utcHours = now.getUTCHours(); const year = now.getUTCFullYear(); const month = now.getUTCMonth(); const date = now.getUTCDate(); // 计算3月第二个周日(夏令时开始) const marchFirstDay = new Date(Date.UTC(year, 2, 1)).getUTCDay(); const marchSecondSunday = 1 + (7 - marchFirstDay) % 7 + 7; const isAfterMarchDSTStart = month > 2 && (month > 3 || date >= marchSecondSunday); // 计算11月第一个周日(夏令时结束) const novemberFirstDay = new Date(Date.UTC(year, 10, 1)).getUTCDay(); const novemberFirstSunday = 1 + (7 - novemberFirstDay) % 7; const isBeforeNovemberDSEnd = month < 10 || (month === 10 && date < novemberFirstSunday); const isDST = isAfterMarchDSTStart && isBeforeNovemberDSEnd; let californiaHours = utcHours - (isDST ? 7 : 8); // 处理跨天情况(UTC时间减时区后为负数) if (californiaHours < 0) { californiaHours += 24; } return { hours: californiaHours }; }
注意事项
- 方案2的夏令时规则需每年确认是否符合美国官方调整,若规则变动需同步更新代码;方案1无需考虑此问题,准确性更高。
- 确保
minDate设置与beforeShowDay的禁用日期逻辑无冲突,两者共同决定最终可选日期范围。
内容的提问来源于stack exchange,提问作者Royal Fleur
相关产品推荐
相关产品推荐

