【问题标题】:How do i use javascript to return the number of days holidays between two dates excluding holidays?我如何使用javascript返回两个日期之间的假期天数,不包括假期?
【发布时间】:2016-11-17 02:45:58
【问题描述】:

我有一个代码返回使用 jquery datapicker 选择的两个日期之间的天数。

我想为假期添加一个函数,它将排除数组中的所有假期; var 假期 [25-12-2016,26-12-2016,1-1-2017];

请在下面找到代码:

            <script>
            <!--Calculate Leave days excluding weekends
            function calcBusinessDays(start, end) {
                // This makes no effort to account for holidays
                // Counts end day, does not count start day

                // make copies we can normalize without changing passed in objects    
                var start = new Date(start);
                var end = new Date(end);

                // initial total
                var totalBusinessDays = 0;

                // normalize both start and end to beginning of the day
                start.setHours(0,0,0,0);
                end.setHours(0,0,0,0);

                var current = new Date(start);
                current.setDate(current.getDate() + 1);
                var day;
                // loop through each day, checking
                while (current <= end) {
                    day = current.getDay();
                    if (day >= 1 && day <= 5) {
                        ++totalBusinessDays;
                    }
                    current.setDate(current.getDate() + 1);
                }
                return totalBusinessDays;
            }

                $(function() {
                $( "#start_date" ).datepicker({ minDate:0, showOn: 'button', buttonImageOnly: true, buttonImage: 'images/calendar.png', beforeShowDay: $.datepicker.noWeekends });
                    $( "#end_date" ).datepicker({ minDate:0, showOn: 'button', buttonImageOnly: true, buttonImage: 'images/calendar.png',beforeShowDay: $.datepicker.noWeekends,
                    onSelect: function (dateStr) {
                    var max = $(this).datepicker('getDate'); // Get selected date
                    $('#datepicker').datepicker('option', 'maxDate', max || '+1Y+12M'); // Set other max, default to +18 months
                    var start = $("#start_date").datepicker("getDate");
                    var end = $("#end_date").datepicker("getDate");
                    var days = (end - start) / (1000 * 60 * 60 * 24);
                    var diff = calcBusinessDays(start,end);
                    $("#leave_days").val(diff);

                } });

              });



            </script>

  <input name="start_date" type="text"   id="start_date"  />  

 <input name="end_date" type="text"   id="end_date" /> 

 <input  name="leave_days" type="text"  id="leave_days" size="32" class="form-control"/>  

【问题讨论】:

  • 您将不得不将所有假期添加到一个数组中,并在您的同时比较它们..
  • 我同意@Naruto...确定这个数组也很有趣...一个很好的开始是here。某些假期被定义为(例如)“一个月的第一个星期一”,而不是固定日期。因此,必须每年对 aray 进行审查。祝你好运!
  • 编辑我的第一条评论:在某个地方建立一个数据库会很好......你只需要记住两件事:定期假期(圣诞节或新年等......他们总是在 25/ 12 OR 01/01)和可变的(需要在旅途中添加......)
  • 我的问题是你如何用函数做到这一点。我需要一个函数来从天数中扣除假期

标签: javascript php jquery calendar


【解决方案1】:

就像在 cmets 中所说的,您必须定义假期数组。

对于这个例子,我定义了两个日期:2016-11-23 和 2016-12-02

您可以使用数据库或在脚本中手动执行,以便随着时间的推移维护相关日期。
这部分这里就不解释了,但是在脚本中,我使用了the default MySQL date format,也就是YYYY-MM-DD。
从数据库中获取假期日期应该很容易。

一个附加函数用于将current日期转换成这个MySQL日期格式,以便比较它。 然后,在while 循环中,我们检查日期是否为假日,如果是,则设置一个布尔标志,用于在条件中向计数器添加“工作日”或不添加“工作日”。

var holiday_array=["2016-11-23", "2016-12-02"];   // YYYY-MM-DD (Default MySQL date format)

function dateToMySQL (x){
    var MySQL_day = x.getDate();
    if(MySQL_day<10){
        MySQL_day = "0"+MySQL_day;      // Leading zero on day...
    }
    var MySQL_month = x.getMonth()+1;   // Months are zero-based.
    if(MySQL_month<10){
        MySQL_month = "0"+MySQL_month;  // Leading zero on month...
    }
    var MySQL_year = x.getYear()+1900;  // Years are 1900 based.
    var MySQL_date = MySQL_year+"-"+MySQL_month+"-"+MySQL_day;
    return MySQL_date;
}

function calcBusinessDays(start, end) {
    // This makes no effort to account for holidays
    // Counts end day, does not count start day

    // make copies we can normalize without changing passed in objects    
    var start = new Date(start);
    var end = new Date(end);

    // initial total
    var totalBusinessDays = 0;

    // normalize both start and end to beginning of the day
    start.setHours(0,0,0,0);
    end.setHours(0,0,0,0);

    // Prepare loop's variables
    var current = new Date(start);
    current.setDate(current.getDate() + 1);
    var day;
    var holidayFound=false;

    // loop through each day, checking
    while (current <= end) {
        //console.log("current: "+current);

        // Check if current is in the holiday array
        var MySQLdate = dateToMySQL(current);
        console.log("MySQL date: "+MySQLdate);

        if($.inArray(MySQLdate,holiday_array)!=-1){
            console.log("                  ^----------- Holiday!!!");
            holidayFound=true;     // "flag"
        }

        // If current is monday to friday and NOT a holiday
        day = current.getDay();
        if (day >= 1 && day <= 5 && !holidayFound) {
            ++totalBusinessDays;
        }

        // For next iteration
        current.setDate(current.getDate() + 1);
        holidayFound=false;
    }
    return totalBusinessDays;
}

$(function() {
    $( "#start_date" ).datepicker({
        minDate:0,
        showOn: 'button',
        buttonImageOnly: true,
        buttonImage: 'http://www.nscale.net/forums/images/misc/Tab-Calendar.png',    //'images/calendar.png',
        beforeShowDay: $.datepicker.noWeekends
    });
    $( "#end_date" ).datepicker({
        minDate:0,
        showOn: 'button',
        buttonImageOnly: true,
        buttonImage: 'http://www.nscale.net/forums/images/misc/Tab-Calendar.png',    //'images/calendar.png',
        beforeShowDay: $.datepicker.noWeekends,
        onSelect: function (dateStr) {
            var max = $(this).datepicker('getDate'); // Get selected date
            $('#datepicker').datepicker('option', 'maxDate', max || '+1Y+12M'); // Set other max, default to +18 months
            var start = $("#start_date").datepicker("getDate");
            var end = $("#end_date").datepicker("getDate");
            var days = (end - start) / (1000 * 60 * 60 * 24);
            var diff = calcBusinessDays(start,end);
            $("#leave_days").val(diff);

        }
    });
});

CodePen(检查控制台;))

【讨论】:

  • 这太棒了@Louys-Patrice-Bessette。
  • 我意识到当假期数组中的日期是“2016-12-02”时,它不会排除假期中的日期..
  • 我不确定你的最后评论是否理解。 holiday_array 中的日期是阻止 while 循环增加“工作日”计数器的日期。
  • 好的...我刚刚知道了...是的,有一个小故障,日期低于该月的 10。给我几分钟。
  • 几个月都一样...现在应该没问题了。 ;)
【解决方案2】:

你可以使用这个逻辑:

把周末当作假期

function workingDaysBetweenDates(startDate, endDate) {
    var millisecondsPerDay = 86400 * 1000; 
    startDate.setHours(0,0,0,1);  
    endDate.setHours(23,59,59,999);  
    var diff = endDate - startDate;     
    var days = Math.ceil(diff / millisecondsPerDay);
    
    // Subtract two weekend days for every week in between
    var weeks = Math.floor(days / 7);
    days = days - (weeks * 2);

    // Handle special cases
    var startDay = startDate.getDay();
    var endDay = endDate.getDay();
    
    // Remove weekend not previously removed.   
    if (startDay - endDay > 1)         
        days = days - 2;      
    
    // Remove start day if span starts on Sunday but ends before Saturday
    if (startDay === 0 && endDay != 6)
        days = days - 1 ; 
            
    // Remove end day if span ends on Saturday but starts after Sunday
    if (endDay === 6 && startDay !== 0)
        days = days - 1  ;
    
    return days;
}

var a = new Date(2015, 10, 16); 
var b = new Date(2016, 01, 20);
var t = workingDaysBetweenDates(a,b);
alert(t);

希望这会有所帮助!

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2017-01-28
    • 2015-04-25
    • 1970-01-01
    • 2023-03-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多