FreeMarker中计算系统日期与2021-02-18硬编码日期的差值遇解析问题求助
FreeMarker 计算两日期差值的实现方案
核心问题根因
当前实现失效的本质原因是:直接把日期格式的字符串赋值给hardcodedDate变量时,该变量在FreeMarker中属于普通字符串类型,既不是合法的日期/时间类型,也无法直接调用?long内建函数获取毫秒时间戳,整个计算流程从类型匹配环节就已经出错。
之前尝试赋值的两个日期字符串没有经过解析转换,完全没有被FreeMarker识别为日期对象,自然无法参与后续的差值计算。
正确实现步骤
1. 初始化硬编码日期对象
FreeMarker中字符串必须通过匹配格式的解析内建函数,才能转换为可计算的日期类型:
- 纯日期(不带时分秒)用
?date()方法解析 - 带具体时间的日期用
?datetime()方法解析 - 方法入参是和硬编码字符串完全匹配的格式规则
对应你需要硬编码的18/02/2021日期,正确赋值写法为:
<#-- 硬编码2021年2月18日,匹配dd/MM/yyyy的格式规则 --> <#assign hardcodedDate = "18/02/2021"?date("dd/MM/yyyy")>
如果需要沿用之前尝试的英文月份格式硬编码字符串,只要补充对应格式规则即可正确解析:
<#-- 解析"Feb 18, 2021 2:07:30 PM"格式的字符串 --> <#assign hardcodedDate = "Feb 18, 2021 2:07:30 PM"?datetime("MMM dd, yyyy hh:mm:ss a")>
2. 计算两日期的差值
拿到合法的日期对象后,即可通过?long获取毫秒级时间戳,按逻辑计算天数差值,完整可运行代码为:
<#assign hardcodedDate = "18/02/2021"?date("dd/MM/yyyy")> <#-- 计算两个日期的天数差,四舍五入取整 --> <#assign difference = ((record.trandate?long - hardcodedDate?long) / 86400000)?round>
关键注意事项
- 格式串必须和硬编码字符串完全匹配:顺序(日/月/年还是月/日/年)、分隔符(斜杠/逗号/横杠)、AM/PM对应的
a标记错配,都会直接触发解析失败。 - 如果
record.trandate本身是字符串类型而非原生日期类型,需要先按照它的实际格式解析为日期对象,再调用?long获取时间戳,不能直接对字符串调用?long方法。 - 计算差值时优先先算两个时间戳的总差值,再做取整处理,避免分别对两个时间戳换算后的天数取整再相减,出现边界误差。
- 如果不需要取整为整天数,去掉计算逻辑最后的
?round即可,结果单位为天,可保留小数表示带小时的精确差值。
内容的提问来源于stack exchange,提问作者4N335
相关产品推荐
相关产品推荐

