使用 jQuery 實現「存入日期 + 下拉選擇天數 = 提取日期」功能時,若直接將下拉框的字串值與 `Date.getDate()` 相加,會發生字串拼接而非數值相加,導致日期計算錯誤。本文詳細解析錯誤原因並給出修正代碼。
$("#time").change(function () {
var time = $("#time").val(); // 取得字串 "1"、"7"、"90"...
var start = $("#EntTime32").val().replace(/-/g, "/");
var d = new Date(start); // 解析存入日期
d.setDate(d.getDate() + time); // ❌ 錯誤:字串拼接 "27" + "1" = "271"
var s1 = d.getFullYear() + "-" + (d.getMonth() + 1) + "-" + d.getDate();
$('#EntTime31').val(s1);
});
"1"Number + String → String(拼接)d.getDate() 返回數值 27,27 + "1" = "271"d.setDate(271) 會自動向後滾動月份,產生預期外的日期$("#time").change(function () {
var timeStr = $("#time").val(); // "1"
var time = parseInt(timeStr, 10); // ✅ 關鍵:轉為十進位整數
if (isNaN(time)) return; // 防呆:非數值不處理
var startStr = $("#EntTime32").val().replace(/-/g, "/");
var d = new Date(startStr);
if (isNaN(d.getTime())) { alert("存入日期格式錯誤"); return; }
d.setDate(d.getDate() + time); // 數值相加,正確
var s1 = d.getFullYear() + "-" +
String(d.getMonth() + 1).padStart(2, '0') + "-" +
String(d.getDate()).padStart(2, '0'); // 補零格式 2024-01-07
$('#EntTime31').val(s1);
});
| 問題 | 解決 |
|---|---|
| 字串與數值相加變拼接 | parseInt(val, 10) / Number(val) / +val |
| 月份/日期不補零 | String(n).padStart(2,'0') 或手動判斷 |
| 日期解析跨瀏覽器差異 | 統一用 YYYY/MM/DD 或 new Date(year, month-1, day) |
| 下拉框含「請選擇」值為 0 | if (time === 0) return; 或 `` |
// 引入 dayjs (2KB) 或 date-fns
import dayjs from 'dayjs';
$("#time").change(function () {
const days = parseInt($("#time").val(), 10);
if (!days) return;
const start = dayjs($("#EntTime32").val());
if (!start.isValid()) return;
$("#EntTime31").val(start.add(days, 'day').format('YYYY-MM-DD'));
});
核心教訓:任何來自 DOM 的 `.val()`、`.text()`、屬性值皆為字串,參與數學運算前必須顯式轉型。養成 `parseInt(x, 10)` 或 `Number(x)` 的習慣,即可徹底避免此類日期計算錯誤。