【问题标题】:Calendar to show U.S. holidays while scheduling event安排活动时显示美国节假日的日历
【发布时间】:2014-11-26 20:30:58
【问题描述】:

我的客户通常会提前几个月为她的客户安排约会。如果预订发生在美国假日日/周期间,我的客户希望收到计划日期落在美国假日期间的通知(她在假日期间的服务收费更高)。

我的客户只关心以下日期:

  • 新年12月30日-1月2日
  • 三月春假周(三月第三周)
  • 复活节周末(这个日期每年都不一样)
  • 五月阵亡将士纪念日周末
  • 7 月的独立日周末
  • 九月劳动节周末
  • 11 月的周一至周日感恩节周
  • 12 月 22-28 日圣诞节周

我想尽可能地自动执行此操作,这样她就不必每年更新数据库,但这不是她的要求,而是我的要求。 :D 最好将假期日期/规则输入数据库或使用规则来确定约会日期是否在安排约会时的假期日/周内?

如果数据库是答案,我需要一些有关数据库设计以及如何设置事件重复发生的帮助。如果基于规则,我也需要一些帮助(例如确定春假、复活节等)。

我正在使用 MSSQL 2005(可能很快会迁移到 mssql 2008)和 ColdFusion 9。

TIA

【问题讨论】:

  • 我将 Matt Busche 作为选定答案,但我确实根据他的解决方案提供了自己的答案(我希望他获得荣誉)。

标签: sql-server-2008 sql-server-2005 coldfusion


【解决方案1】:

我上个月 wrote a UDF 帮助过许多美国假期,但并没有涵盖所有。这应该给你一个体面的开始。

你也可以使用这个UDF from CFLib 来让你度过复活节

一旦你有阵亡将士纪念日,你可以做一个简单的dateadd() 并花 1 和 2 天来度过一个完整的周末。

<cffunction name="getUSBankHolidays" access="public" output="false" returntype="struct" hint="general bank holidays for US">
  <cfargument name="iYear" default="#Year(now())#" />

    <cfset var currentYear = arguments.iYear />

    <!--- Static dates per year --->
    <cfset var strResult = 
      { NewYears1      = createDate(currentYear,12,30),
        NewYears2      = createDate(currentYear,12,31),
        NewYears3      = createDate(currentYear,1,1),
        NewYears4      = createDate(currentYear,1,2),
        Independence   = createDate(currentYear,7,4),
        Christmas1     = createDate(currentYear,12,22),
        Christmas2     = createDate(currentYear,12,23),
        Christmas3     = createDate(currentYear,12,24),
        Christmas4     = createDate(currentYear,12,25),
        Christmas5     = createDate(currentYear,12,26),
        Christmas6     = createDate(currentYear,12,27),
        Christmas7     = createDate(currentYear,12,28)
  } />

    <cfset strResult.SpringBreak          = createDate(currentYear,3,GetNthOccOfDayInMonth(3,1,3,currentYear)) />
    <cfset strResult.MemorialDay          = createDate(currentYear,5,(DaysInMonth(createDate(2012,5,1))) - (DayOfWeek(createDate(2012,5,DaysInMonth(createDate(2012,5,1)))) - 2)) />
    <cfset strResult.LaborDay             = createDate(currentYear,9,GetNthOccOfDayInMonth(1,2,9,currentYear)) />
    <cfset strResult.Thanksgiving         = createDate(currentYear,11,GetNthOccOfDayInMonth(4,6,11,currentYear)) />

    <cfreturn strResult />
</cffunction>

<cfdump var="#getUSBankHolidays()#">

<!-- This code will tell you if the date is holiday or not --->
<cfset Today = '2012-01-01' />
<cfdump var="#NOT arrayIsEmpty(structFindValue(getUSBankHolidays(),createDate(year(Today),month(Today),day(Today))))#">

您还需要来自 CFLib.org 的 this UDF 才能获得一个月中一天的第 n 次出现。

【讨论】:

  • 任务完成。再次感谢。
  • 虽然很好,但这并没有考虑到周末的假期,因此,出于休假目的,可以提前一天或一天​​后观察。 (例如,当 7 月 4 日是星期六时,每个享受独立日假期的人(通常)都会在 7 月 3 日休息。)
【解决方案2】:

数据库表将为您提供更多的灵活性。

我帮助维护的数据仓库有一个名为 period 的表,其中包含主键的日期。其他领域包括假期、一些财政年度的东西,以及其他一些对我们很重要的领域。其他表有对表的外键引用。

除了使我们能够轻松生成必要的报告外,该表还允许我们使用左连接来识别未发生事件的日期。类似的东西可能对您的情况有用。

就更新而言,我们手动进行。当周末像圣诞节这样的事情时,我们等待被告知我们是周五还是周一休息。

【讨论】:

    【解决方案3】:

    在我看来,我会把它放在代码中。几年前我发现了这一点,并根据其许可协议使用了它。它是基于 Java 的,但我相信您可以根据需要更改为 Coldfusion。它目前列出了 66 个假期的代码,并且确保您可以对其进行一些操作来计算您需要的星期。

    http://mindprod.com/applet/holidays.html

    http://mindprod.com/precis/holidays.txt

    https://wush.net/websvn/mindprod/listing.php?repname=mindprod&path=%2Fcom%2Fmindprod%2Fholidays%2F

    【讨论】:

      【解决方案4】:

      这是我最终使用的,并且足够灵活,可以在将来修改,我可能仍会将其转换为带有 GUI 的数据库驱动系统,以添加未来的日期,但现在,这很好用。

      <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> 
      <html xmlns="http://www.w3.org/1999/xhtml"> 
      <head> 
      <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> 
      <title>Untitled Document</title> 
      <link rel="stylesheet" href="http://code.jquery.com/ui/1.9.2/themes/base/jquery-ui.css" /> 
      <script src="http://code.jquery.com/jquery-1.8.3.js"></script> 
      <script src="http://code.jquery.com/ui/1.9.2/jquery-ui.js"></script> 
      <link rel="stylesheet" href="http://jqueryui.com/resources/demos/style.css" /> 
      <script> 
      $(document).ready(function(){ 
        $( ".datepicker" ).datepicker({ 
          changeMonth: true, 
          changeYear: true 
        }); 
      }); 
      </script> 
      </head> 
      
      <body> 
      <cfoutput> 
      <form action="#cgi.SCRIPT_NAME#" method="post"> 
        Start Date: <input type="text" name="StartDate" class="datepicker" /> (mm-dd-yyyy)<br /> 
        End Date: <input type="text" name="EndDate" class="datepicker" /> (mm-dd-yyyy) <br /> 
        <input type="submit" value="Save Appointment" /> 
      </form> 
      <cfif structkeyexists(form,'startDate')> 
      <cfdump var="#form#" expand="no"> 
      <hr /> 
      <cfscript> 
      /** 
      * Returns the day of the month(1-31) of an Nth Occurrence of a day (1-sunday,2-monday etc.)in a given month. * 
      * @param NthOccurrence      A number representing the nth occurrence.1-5. 
      * @param TheDayOfWeek      A number representing the day of the week (1=Sunday, 2=Monday, etc.). 
      * @param TheMonth      A number representing the Month (1=January, 2=February, etc.). 
      * @param TheYear      The year. 
      * @return Returns a numeric value. 
      * @author Ken McCafferty (mccjdk@yahoo.com) 
      * @version 1, August 28, 2001 
      */
      function GetNthOccOfDayInMonth(NthOccurrence,TheDayOfWeek,TheMonth,TheYear) 
      {
        Var TheDayInMonth=0; 
        if(TheDayOfWeek lt DayOfWeek(CreateDate(TheYear,TheMonth,1))){ 
          TheDayInMonth= 1 + NthOccurrence*7  + (TheDayOfWeek - DayOfWeek(CreateDate(TheYear,TheMonth,1))) MOD 7; 
        } 
        else { 
          TheDayInMonth= 1 + (NthOccurrence-1)*7  + (TheDayOfWeek - DayOfWeek(CreateDate(TheYear,TheMonth,1))) MOD 7; 
        } 
        //If the result is greater than days in month or less than 1, return -1
        if(TheDayInMonth gt DaysInMonth(CreateDate(TheYear,TheMonth,1)) OR   TheDayInMonth lt 1){ 
          return -1; 
        } 
        else { 
          return TheDayInMonth; 
        } 
      } 
      /** 
      * Returns the date for Easter in a given year.
      * Minor edits by Rob Brooks-Bilson (rbils@amkor.com).
      * 
      * @param TheYear      The year to get Easter for. 
      * @return Returns a date object. 
      * @author Ken McCafferty (rbils@amkor.commccjdk@yahoo.com) 
      * @version 1, September 4, 2001 
      */
      function GetEaster() {
        Var TheYear=iif(arraylen(arguments) gt 0,"arguments[1]", "Year(Now())"); 
        Var century = Int(TheYear/100);
        Var G = TheYear MOD 19;
        Var K = Int((century - 17)/25);
        Var I = (century - Int(century/4) - Int((century - K)/3) + 19*G + 15) MOD 30;
        Var H = I - Int((I/28))*(1 - Int((I/28))*Int((29/(I + 1)))*Int(((21 - G)/11)));
        Var J = (TheYear + Int(TheYear/4) + H + 2 - century + Int(century/4)) MOD 7;
        Var L = H - J;
        Var EasterMonth = 3 + Int((L + 40)/44);
        Var EasterDay = L + 28 - 31*Int((EasterMonth/4));
        return CreateDate(TheYear,EasterMonth,EasterDay);
      }
      
      function LastDayOfMonth(strMonth) {
        var strYear=Year(Now());
        if (ArrayLen(Arguments) gt 1)
          strYear=Arguments[2];
        return DateAdd("d", -1, DateAdd("m", 1, CreateDate(strYear, strMonth, 1))); 
      }
      </cfscript>
      
      <cfset StartYear = listlast(StartDate,'/')>
      <cfset EndYear = listlast(endDate,'/')>
      <cfset HolidaySchedule = structnew()>
      <cfloop index="currentYear" from="#dateformat(StartDate,'yyyy')#" to="#dateformat(EndDate,'yyyy')#" step="1"> 
      <cfset val = StructInsert( HolidaySchedule, "Independence (#currentYear#)", createDate(currentYear,7,4) )/> 
      <cfset val = StructInsert( HolidaySchedule, "New Year (#currentYear#)", createdate(currentYear,1,1) )/> 
      <cfset val = StructInsert( HolidaySchedule, "Easter (#currentYear#)", GetEaster(currentYear) )/> 
      <cfset val = StructInsert( HolidaySchedule, "Spring Break (#currentYear#)", createDate(currentYear,3,GetNthOccOfDayInMonth(2,2,3,currentYear)) )/>
      <cfset val = StructInsert( HolidaySchedule, "Labor Day (#currentYear#)", createDate(currentYear,9,GetNthOccOfDayInMonth(1,2,9,currentYear)) )/>
      <cfset val = StructInsert( HolidaySchedule, "Thanksgiving (#currentYear#)", createDate(currentYear,11,GetNthOccOfDayInMonth(4,6,11,currentYear)) )/>
      <cfset val = StructInsert( HolidaySchedule, "Christmas Day (#currentYear#)", createdate(currentYear,12,25) )/>
      </cfloop>
      <cfdump var="#HolidaySchedule#" expand="no">
      <cfset normalweek = 'true'>
      <cfloop index="x" from="#startDate#" to="#endDate#" step="1">
      Checking date: #dateformat(x,'yyyy-mm-dd')#<br />
      <cfif NOT arrayIsEmpty(structFindValue(HolidaySchedule,createDate(year(x),month(x),day(x))))> 
      <div style="background-color:##009900; color:##ffffff">#dateformat(x, 'mm/dd/yyyy')# is a holiday.</div> 
      <cfset normalweek = 'false'>
      </cfif>
      </cfloop>
      
      <cfif normalweek eq 'false'>
      Remember to add on the Holiday Fee.
      <cfelse>
      No additional charges for this appointment.
      </cfif>
      </cfif>
      </cfoutput>
      </body>
      </html>
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2022-01-02
        • 2017-11-09
        • 2020-11-30
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多