VB转换美制日期字符串为英制格式时单数字月日处理异常
问题根因
转换不稳定是两个代码缺陷共同导致的:
- 正则规则完全不匹配实际输入格式:你写的正则
^(\d{2})(\d{2})(\d{4})$仅能匹配无分隔符、月日固定为2位的8位纯数字串,但实际Split拆分后得到的日期段是带/分隔符的美制格式(如3/13/2022、4/1/2022),正则根本不会触发替换,所有日期都靠VB的隐式类型转换硬识别。 - 隐式日期识别存在歧义:对于
3/13/2022这类日期,因为13不可能作为月份取值,VB不管系统区域怎么设置都能正确识别;但对于4/1/2022这类月、日取值都在1-12范围内的日期,VB会跟随系统区域设置判断月、日位置,一旦区域配置有波动就会出现月日互换的错误,表现为转换结果时好时坏。
修复方案
不要依赖隐式类型转换和字符串硬替换,通过正则明确捕获美制日期的月、日、年字段,显式构造日期类型后再做格式化,从根源上消除歧义,同时正则要兼容1位/2位的月、日字段:
X = 3 ' 初始化正则,匹配M/d/yyyy格式的美制日期,兼容1-2位月、日 re.Pattern = "^(\d{1,2})/(\d{1,2})/(\d{4})$" Do While strTimeStamp = 0 If InStr(WS2.Cells(lRow, lCol), "TIMESTAMP") <> 0 Then strHPCStats = Split(WS2.Cells(lRow, lCol), " ") ' 正则匹配捕获月、日、年分组 Set matches = re.Execute(strHPCStats(X)) If matches.Count = 1 Then ' 显式通过DateSerial构造日期,完全规避区域设置导致的识别错误 dt = DateSerial(CInt(matches(0).SubMatches(2)), CInt(matches(0).SubMatches(0)), CInt(matches(0).SubMatches(1))) ' 格式化为要求的英制日期格式 strTimeStamp = Format$(dt, "dd/mmm/yyyy") End If WS2.Cells(lRow, lCol).EntireRow.Delete lRow = lRow - 1 Else WS2.Cells(lRow, lCol).EntireRow.Delete lRow = lRow - 1 End If lRow = lRow + 1 Loop
注意:需提前确保正则对象
re已正常创建,若要兼容日期段前后可能存在的多余空格,可将正则Pattern修改为^\s*(\d{1,2})/(\d{1,2})/(\d{4})\s*$提升容错性。
内容的提问来源于stack exchange,提问作者Andy M
相关产品推荐
相关产品推荐

