【问题标题】:How to exclude Japan bank holidays and only add working days to a date in Google Apps Script?如何排除日本银行假日并仅在 Google Apps 脚本中的日期中添加工作日?
【发布时间】:2021-01-08 15:33:49
【问题描述】:

目标: 我正在尝试根据用户编辑单元格的日期添加 1 到 3 天来进行日期计算。以下是希望具备的主要条件。

  1. 如果在周一至周四的下午 2:00 到下午 6:30 (JST) 之间,则将当前日期加 1 天。
  2. 如果是在星期五下午 2:00 到下午 6:30 (JST) 之间,则将当前日期加上 3 天以在星期一得到它,避免得到周末日期。
  3. 如果星期一或任何其他工作日不是基于日本银行假日系统的工作日,我想添加所需的天数,直到我们可以得到下一个工作日。例如,2021 年 1 月 11 日是星期一,但是对于日本来说,这是一个银行假日,所以在这种情况下,我希望得到 1 月 12 日。

问题 我不知道如何或者是否有可能以某种方式自动添加日期并始终获得基于日本银行假日系统的工作日。

当前代码 这是我目前拥有的代码,这是我从@NaziA 收到的,它很好用,因为它不包括周末。但我只是想知道我们是否可以更进一步,排除日本的银行假日,只获得日本的工作日。 Continuation to this question.

function onEdit(e) { 
  const sheetName = 'Status';
  const statusSheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName(sheetName);
  const cell = statusSheet.getActiveCell();
  const row = cell.getRow();
  const column = cell.getColumn();
  const editedRangeValue = cell.getValue();

  // var currentDate = new Date(new Date().toLocaleString('en-US', { timeZone: 'Japan' }));

  // The above line of code translates your time into japan timezone but since 
  // sheets is converting your timezone automatically to the regional one, 
  // it adjusts an additional day when used. Be careful in using the above line.

  var currentDate = new Date();

  // Use the line below to test different time slots, we do not want to wait the 
  // exact time just to test this script.
  // currentDate.setHours(11, 30, 0 ,0);

  startDate = new Date(currentDate.getTime());
  startDate.setHours(9, 30, 0, 0);

  endDate1 = new Date(currentDate.getTime());
  endDate1.setHours(14, 0, 0, 0);

  endDate2 = new Date(currentDate.getTime());
  endDate2.setHours(18, 30, 0, 0);

  // Column numbers for Status sheet
  const caseTypeColumnStatus = 4;

  if (sheetName == 'Status' && column == caseTypeColumnStatus && row > 15 && editedRangeValue == 'Chat => Email') {
    var statusColumn = column + 3;
    if (startDate <= currentDate && endDate1 > currentDate) { // If the current time is between 9:30 A.M. and 2:00 P.M. (JST), then TRUE. 
      // Insert today's date
      statusSheet.getRange(row, statusColumn).setValue(currentDate);
    } else if (endDate1 <= currentDate && endDate2 > currentDate) { // If the current time is between 2:00 P.M. and 6:30 P.M. (JST), then TRUE.
      // Insert tomorrow's date
      var tomorrow = new Date(currentDate.setDate(currentDate.getDate() + 1));
      if(tomorrow.getDay() == 6){ 
        // if saturday, add 2 days 
        tomorrow.setDate(tomorrow.getDate() + 2);
      } 
      else if(tomorrow.getDay() == 0){
        // if sunday, add 1 day
        tomorrow.setDate(tomorrow.getDate() + 1);
      } 
      statusSheet.getRange(row, statusColumn).setValue(tomorrow);
    }
  }
}

【问题讨论】:

    标签: google-apps-script


    【解决方案1】:

    抱歉,花了一些时间。我创建了一个单独的函数来计算周末和节假日的偏移量。

    我的测试用例写在下面的注释中,请将它们注释掉,以便您查看行为。

    这些测试用例是极端的,所以当它们给出预期的结果时,你应该在其他日期也很好。 (例如连续/连续假期、假期+周末和明年假期加周末)

    function onEdit(e) { 
      const sheetName = 'Status';
      const statusSheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName(sheetName);
      const cell = statusSheet.getActiveCell();
      const row = cell.getRow();
      const column = cell.getColumn();
      const editedRangeValue = cell.getValue();
    
      var currentDate = new Date(new Date().toLocaleString('en-US', { timeZone: 'Japan' }));
      // var currentDate = new Date();
      // Testing next day of April 28, 2021 = > should be May 6, 2021
      // currentDate.setFullYear(2021);
      // currentDate.setMonth(3);
      // currentDate.setDate(28);
      // currentDate.setHours(15, 30, 0 ,0);
      // Testing next day of December 31, 2020 => should be January 4, 2021
      // currentDate.setFullYear(2020);
      // currentDate.setMonth(11);
      // currentDate.setDate(31);
      // currentDate.setHours(15, 30, 0 ,0);
      // Check date if value assigned is correct
      // Logger.log(currentDate);
    
      startDate = new Date(currentDate.getTime());
      startDate.setHours(9, 30, 0, 0);
    
      endDate1 = new Date(currentDate.getTime());
      endDate1.setHours(14, 0, 0, 0);
    
      endDate2 = new Date(currentDate.getTime());
      endDate2.setHours(18, 30, 0, 0);
    
      // Column numbers for Status sheet
      const caseTypeColumnStatus = 4;
    
      if (sheetName == 'Status' && column == caseTypeColumnStatus && row > 15 && editedRangeValue == 'Chat => Email') {
        var statusColumn = column + 3;
        if (startDate <= currentDate && endDate1 > currentDate) { // If the current time is between 9:30 A.M. and 2:00 P.M. (JST), then TRUE. 
          // Insert today's date with the hour set to 00:00:00
          // Calling holidayWeekendOffset for same day just in case 
          // a user edits the sheet data during weekends/holidays. 
          // It will just adjust when it's not a weekday
          currentDate = new Date(currentDate.getFullYear(), currentDate.getMonth(), currentDate.getDate());
          currentDate = holidayWeekendOffset(currentDate);
          statusSheet.getRange(row, statusColumn).setValue(currentDate);
          // Check output
          // Logger.log(currentDate);
        } else if (endDate1 <= currentDate && endDate2 > currentDate) { // If the current time is between 2:00 P.M. and 6:30 P.M. (JST), then TRUE.
          // Insert tomorrow's date with the hour set to 00:00:00
          currentDate = new Date(currentDate.getFullYear(), currentDate.getMonth(), currentDate.getDate());
          var tomorrow = new Date(currentDate.setDate(currentDate.getDate() + 1));
          // Adjust tomorrow's date based on holidays and weekends
          tomorrow = holidayWeekendOffset(tomorrow);
          statusSheet.getRange(row, statusColumn).setValue(tomorrow);
          // Check output
          // Logger.log(tomorrow);
        }
      }
    }
    
    function holidayWeekendOffset(day) {
      var today = day;
      // define holidays, should be in ascending order so successive holidays can be caught properly
      var holidays = [{month: 1.0, date: 1.0},
                      {month: 1.0, date: 11.0},
                      {month: 2.0, date: 11.0},
                      {month: 2.0, date: 23.0},
                      {month: 3.0, date: 20.0},
                      {month: 4.0, date: 29.0},
                      {month: 4.0, date: 30.0},
                      {month: 5.0, date: 1.0},
                      {month: 5.0, date: 2.0},
                      {month: 5.0, date: 3.0},
                      {month: 5.0, date: 4.0},
                      {month: 5.0, date: 5.0},
                      {month: 7.0, date: 22.0},
                      {month: 7.0, date: 23.0},
                      {month: 8.0, date: 8.0},
                      {month: 9.0, date: 20.0},
                      {month: 9.0, date: 23.0},
                      {month: 11.0, date: 3.0},
                      {month: 11.0, date: 23.0}]
    
      holidays.forEach(function (holiday) {
        if (today.getDate() == holiday.date && today.getMonth() + 1 == holiday.month){
          today.setDate(today.getDate() + 1);
        }
      });
      while (today.getDay() == 6 || today.getDay() == 0) {
        today.setDate(today.getDate() + 1);
      }
      return today;
    }
    

    有像this 这样的库可用,但我避免使用它,因为我不确定它是否会不时更新。至少有了这个,您可以控制该函数并可以按照您想要的方式定义它。

    【讨论】:

    • 嗨@NaziA,我对这里的延迟回复表示诚挚的歉意......这完全有效。我非常感谢您的快速支持!
    • 很高兴听到@JohnT。不用担心。
    猜你喜欢
    • 1970-01-01
    • 2015-06-03
    • 1970-01-01
    • 2020-04-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多