在WSO2中用Script Mediator处理日期减365天的问题及替代方案
问题解决:日期减一年并保持格式(Script Mediator修正+替代方案)
一、修正你的Script Mediator代码
你的代码存在两个核心问题:
- 直接减去
365是错误的——getTime()返回的是毫秒数,需要计算365天对应的毫秒数(365*24*60*60*1000) - 得到时间戳后没有重新格式化为原日期字符串,直接输出了毫秒数
修正后的代码如下:
<script language="js"><![CDATA[ var log = mc.getServiceLog(); log.info("Logging inside Script Mediator"); var simpleDateFormat = Packages.java.text.SimpleDateFormat; var end_date = mc.getProperty('DATE'); // 匹配输入的日期格式 var format = new simpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSSXXX"); var d1 = format.parse(end_date); // 计算365天的毫秒数(用长整型避免数值溢出) var oneYearInMillis = 365 * 24 * 60 * 60 * 1000; var startDateMillis = d1.getTime() - oneYearInMillis; // 转换为Date对象并重新格式化 var start_date = new Packages.java.util.Date(startDateMillis); var formattedStartDate = format.format(start_date); log.info("Start Date::" + formattedStartDate); // 将结果存回属性供后续流程使用 mc.setProperty('START_DATE', formattedStartDate); ]]></script>
执行后会输出预期的2021-10-10T23:12:18.948+05:30格式字符串。
二、不使用Script Mediator的替代方案
方案1:使用Property Mediator+表达式(最简洁)
利用WSO2内置的XPath日期函数直接计算,无需额外脚本:
<property name="START_DATE" expression="fn:format-dateTime( fn:subtract-dateTime-dayTimeDuration( xs:dateTime(get-property('DATE')), xs:dayTimeDuration('P365D') ), '[Y0001]-[M01]-[D01]T[H01]:[m01]:[s01].[f000][Z]' )"/>
xs:dateTime将字符串转为标准日期时间类型fn:subtract-dateTime-dayTimeDuration实现减去365天的操作fn:format-dateTime将计算结果格式化为目标字符串格式
方案2:使用XSLT Mediator
适合需要处理复杂日期逻辑的场景,编写XSLT文件:
创建subtract-one-year.xslt文件:
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:mc="http://ws.apache.org/ns/synapse"> <xsl:template match="/"> <xsl:variable name="input-date" select="mc:get-property('DATE')"/> <xsl:variable name="date-time" select="xs:dateTime($input-date)"/> <!-- 减去365天的时长 --> <xsl:variable name="result-date" select="$date-time - xs:dayTimeDuration('P365D')"/> <!-- 格式化回目标格式 --> <xsl:variable name="formatted-date" select="format-dateTime($result-date, '[Y0001]-[M01]-[D01]T[H01]:[m01]:[s01].[f000][Z]')"/> <!-- 将结果设置回消息属性 --> <xsl:value-of select="mc:set-property('START_DATE', $formatted-date)"/> </xsl:template> </xsl:stylesheet>
在Sequence中引用该XSLT:
<xslt key="classpath:subtract-one-year.xslt"/>
方案3:使用自定义Class Mediator
适合需要复用复杂日期处理逻辑的场景,编写Java类:
import org.apache.synapse.MessageContext; import org.apache.synapse.mediators.AbstractMediator; import java.text.SimpleDateFormat; import java.util.Date; public class DateSubtractMediator extends AbstractMediator { @Override public boolean mediate(MessageContext mc) { try { String endDateStr = (String) mc.getProperty("DATE"); SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSSXXX"); Date endDate = sdf.parse(endDateStr); long oneYearInMillis = 365L * 24 * 60 * 60 * 1000; Date startDate = new Date(endDate.getTime() - oneYearInMillis); String formattedStartDate = sdf.format(startDate); mc.setProperty("START_DATE", formattedStartDate); return true; } catch (Exception e) { getLog(mc).error("Failed to subtract one year from date", e); return false; } } }
将编译后的jar包放入WSO2的repository/components/lib目录,然后在Sequence中调用:
<class name="com.yourpackage.DateSubtractMediator"/>
内容的提问来源于stack exchange,提问作者Ruby
相关产品推荐
相关产品推荐

