You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

求可根据指定日期识别美国节假日名称的Freemarker方法

解决方案

Freemarker本身没有内置的美国节假日判断函数,你需要自定义一个节假日校验函数,再修改原有的getPreviousBusinessDay逻辑,确保返回的日期既不是周末也不在公司认可的节假日列表里。

步骤1:实现节假日判断函数isUSHoliday

先编写一个函数来判断指定日期是否属于你公司认可的10个美国节假日。下面是包含常见美国节假日判断逻辑的示例(你可以根据公司实际规则调整调休或节假日范围):

<#function isUSHoliday date>
  <#local year = date?date_part("yyyy")?number>
  <#local month = date?date_part("MM")?number>
  <#local day = date?date_part("dd")?number>
  <#local dayOfWeek = date?day_of_week> <!-- 1=周日, 2=周一, ...,7=周六 -->

  <!-- 1. 新年(1月1日,若周末则调休到周一/周五) -->
  <#if (month == 1 && day == 1) || (month == 12 && day == 31 && dayOfWeek == 7) || (month == 1 && day == 2 && dayOfWeek == 2)>
    <#return true>
  </#if>

  <!-- 2. 马丁路德金纪念日(1月第三个周一) -->
  <#if month == 1>
    <#local firstMonday = 1 + (2 - dayOfWeek + 7) % 7> <!-- 当月第一个周一的日期 -->
    <#local thirdMonday = firstMonday + 14>
    <#if day == thirdMonday>
      <#return true>
    </#if>
  </#if>

  <!-- 3. 总统日(2月第三个周一) -->
  <#if month == 2>
    <#local firstMonday = 1 + (2 - dayOfWeek + 7) % 7>
    <#local thirdMonday = firstMonday + 14>
    <#if day == thirdMonday>
      <#return true>
    </#if>
  </#if>

  <!-- 4. 阵亡将士纪念日(5月最后一个周一) -->
  <#if month == 5>
    <#local lastDayOfMay = 31>
    <#local lastDayOfWeek = (date?date("yyyy-MM-31")?day_of_week)>
    <#local lastMonday = lastDayOfMay - (lastDayOfWeek - 2 + 7) % 7>
    <#if day == lastMonday>
      <#return true>
    </#if>
  </#if>

  <!-- 5. 独立日(7月4日,周末则调休到周一/周五) -->
  <#if (month ==7 && day ==4) || (month ==7 && day ==3 && dayOfWeek ==7) || (month ==7 && day ==5 && dayOfWeek ==2)>
    <#return true>
  </#if>

  <!-- 6. 劳动节(9月第一个周一) -->
  <#if month ==9>
    <#local firstMonday = 1 + (2 - dayOfWeek +7) %7>
    <#if day == firstMonday>
      <#return true>
    </#if>
  </#if>

  <!-- 7. 哥伦布日(10月第二个周一) -->
  <#if month ==10>
    <#local firstMonday =1 + (2 - dayOfWeek +7) %7>
    <#local secondMonday = firstMonday +7>
    <#if day == secondMonday>
      <#return true>
    </#if>
  </#if>

  <!-- 8. 退伍军人节(11月11日,周末调休) -->
  <#if (month ==11 && day ==11) || (month ==11 && day ==10 && dayOfWeek ==7) || (month ==11 && day ==12 && dayOfWeek ==2)>
    <#return true>
  </#if>

  <!--9. 感恩节(11月第四个周四) -->
  <#if month ==11>
    <#local firstThursday =1 + (5 - dayOfWeek +7) %7> <!-- 周四对应day_of_week=5 -->
    <#local fourthThursday = firstThursday +21>
    <#if day == fourthThursday>
      <#return true>
    </#if>
  </#if>

  <!--10. 圣诞节(12月25日,周末调休) -->
  <#if (month ==12 && day ==25) || (month ==12 && day ==24 && dayOfWeek ==7) || (month ==12 && day ==26 && dayOfWeek ==2)>
    <#return true>
  </#if>

  <!-- 非节假日 -->
  <#return false>
</#function>

步骤2:修改getPreviousBusinessDay函数,加入节假日校验

修改原函数,让它递归调用自身,直到返回的日期既不是周末也不是节假日:

<#function getPreviousBusinessDay date>
  <#local dateAsEpochMS = date?long>
  <#local outieDate>
  
  <#local dayOfWeek = date?day_of_week> <!-- 1=周日, 2=周一, ...,7=周六 -->
  <#if dayOfWeek == 2> <!-- 周一 -->
    <#local outieDate = (dateAsEpochMS - 3*86400000)?number_to_date>
  <#elseif dayOfWeek == 1> <!-- 周日 -->
    <#local outieDate = (dateAsEpochMS - 2*86400000)?number_to_date>
  <#else> <!-- 周二到周六 -->
    <#local outieDate = (dateAsEpochMS - 86400000)?number_to_date>
  </#if>

  <!-- 检查是否是节假日,如果是则递归调用继续往前推 -->
  <#if isUSHoliday(outieDate)>
    <#return getPreviousBusinessDay(outieDate)>
  <#else>
    <#return outieDate?string("MMMM d, YYYY")>
  </#if>
</#function>

测试示例

比如,如果July 29, 2022是公司节假日,调用:

${getPreviousBusinessDay("August 1, 2022"?date)}

函数会先返回July 29, 2022,检测到是节假日后,继续往前推到July 28, 2022(如果该日期不是节假日则返回)。

注意事项

  • 你可以根据公司实际认可的节假日调整isUSHoliday函数里的规则,比如某些公司可能不执行调休,只按实际日期判定节假日。
  • 递归调用的方式简单直接,如果需要处理跨多个节假日的极端情况,也可以改用循环逻辑避免栈溢出(不过一般节假日连续不超过2天,递归足够覆盖需求)。

内容的提问来源于stack exchange,提问作者Pretentious Beer

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.22 06:39:13