Apps Script中如何正确校验数组非空项的月/日/年格式日期?
Google Apps Script 数组日期格式校验方案
现有方法的问题分析
正则表达式校验的问题
你当前的正则^\d{1,2}/\d{1,2}/\d{2,4}$存在两个核心问题:
- 类型不匹配:如果数组中的日期是数字类型(比如
3/31/19被JS解析为除法运算结果),正则无法匹配数字,会误判为无效格式。 - 仅校验格式,不校验日期合法性:比如
13/32/99这种格式符合但实际不存在的日期,正则会判定为有效,但实际是非法日期。
Date构造函数校验的问题
直接用new Date(array[i])结合isNaN(date.getTime())的方式,会把纯数字(比如34)误判为有效日期——因为数字会被当作Unix时间戳(从1970年1月1日开始的毫秒数),new Date(34)会生成一个合法的早期日期,导致校验失效。
最优校验方案
结合格式正则校验+日期合法性校验,同时处理元素类型问题,确保既匹配格式,又验证日期真实有效。
代码实现
function isDateOrEmpty(array) { const result = {}; // 匹配月/日/年格式的正则,使用字面量写法更简洁 const dateRegex = /^\d{1,2}\/\d{1,2}\/\d{2,4}$/; for (let i = 0; i < array.length; i++) { const item = array[i]; // 跳过空条目 if (item === '') continue; // 先把元素转为字符串,统一处理类型 const strItem = String(item).trim(); // 第一步:校验格式是否符合要求 if (!dateRegex.test(strItem)) { // 格式不符,记录错误(i+2对应表格行号,保持你原逻辑) result[i + 2] = "Not Date format"; continue; } // 第二步:校验日期是否真实有效,避免格式合法但日期不存在的情况 const [month, day, year] = strItem.split('/').map(Number); // 处理两位年份:默认视为1970-2069区间(可根据需求调整) const fullYear = year < 100 ? (year >= 70 ? 1900 + year : 2000 + year) : year; // 创建Date对象,注意月份是0-11,所以要减1 const date = new Date(fullYear, month - 1, day); // 验证日期是否与输入一致(避免Date自动修正非法日期,比如2/30/2023会被转为3/2/2023) if ( date.getFullYear() !== fullYear || date.getMonth() !== month - 1 || date.getDate() !== day ) { result[i + 2] = "Invalid Date"; } } return result; } // 测试示例数组 const testArray = ['3/31/19', '8/22/2021', '2/1/2022', 34, 'test']; console.log(isDateOrEmpty(testArray)); // 输出:{5: "Not Date format", 6: "Not Date format"} 对应原数组的34和test
代码说明
- 统一类型处理:将所有数组元素转为字符串并去除首尾空格,避免数字类型干扰。
- 格式校验:用正则确保条目符合
月/日/年的结构,月、日1-2位,年2-4位。 - 日期合法性校验:
- 拆分字符串为月、日、年,转换为数字。
- 处理两位年份(可根据业务需求调整区间,比如这里默认2位年≥70则为19xx,否则为20xx)。
- 创建Date对象时,月份需减1(因为JS中月份是0-11)。
- 对比Date对象的年、月、日与输入值是否一致,避免Date自动修正非法日期(比如2月30日)。
测试结果
针对示例数组['3/31/19', '8/22/2021', '2/1/2022', 34, 'test'],校验后会正确识别34和test为非日期格式,返回对应的错误信息。
内容的提问来源于stack exchange,提问作者Shaik Naveed
相关产品推荐
相关产品推荐

