如何获得周末后新月份的第一个工作日?

How to get the first business day in a new month after the weekend?

如何巧妙地获取周末后一个月的第一个工作日?

要获取月份的第一个工作日(给定 dateInput),我们可以这样做:

firstBusdayMonth = fbusdate(year(dateInput),month(dateInput));

例如,对于 11 月,使用上述函数将 return 11 月 1 日星期四作为第一个工作日。但是,第一个周末之后的月份的第一个工作日是 11 月 5 日星期一。我怎样才能得到后一个日期?

备注:

  • 周末不必在同一个月。
  • 如果星期一不是工作日,那么我希望return下一个工作日

我会在你的陈述之后添加这样的内容:

[DayNumber, DayName] = weekday(firstBusdayMonth);
if DayNumber > 2
    day = 10 - DayNumber;
else

这是可行的,因为 'weekday' 将 return 一个介于 1(星期日)和 7(星期六)之间的数字。

fbusdate() 函数永远不会 return 1 或 7,因此我们可以忽略这些情况。

如果 weekday(fbusdate()) == 2,第一个是星期一,不需要更改 firstBusdayMonth 变量。

如果 weekday(firstBusdayMonth) returns 在 2 和 6 之间,我们需要跳到下一周,所以我们用 10 减去工作日值来找到下一个星期一。

它可能不是优雅的解决方案,但应该可行。

这个函数可以解决问题。逻辑如下:

  • 为给定月份的所有日期创建一个日期时间数组。
  • 获取天数。
  • 创建一个逻辑数组,从第一个星期一开始为真(所以在第一个周末之后,占上个月的最后一天是星期日)。
  • 使用 isbusday 创建另一个逻辑数组以排除非工作日的星期一。
  • 找到这两个逻辑数组为真的第一天数字,因此是周末后的第一个工作日。

代码:

function d = fbusdateAferWE( y, m )
    % Inputs: y = year, m = month
    % Outputs: day of the month, first business day after weekend

    % Create array of days for the given month
    dates = datetime( y, m, 1 ):days(1):datetime( y, m, eomday( y, m ) );
    % Get the weekday numbers to find first Monday, 1 = Sunday
    dayNum = weekday( dates );                   
    % Create the logical array to determine days from first Monday
    afterFirstWeekend = ( cumsum(dayNum==2) > 0 ).'; 
    % Get first day which is afterFirstWeekend and a business day.
    d = find( afterFirstWeekend & isbusday( dates ), 1 );    
end

您可以不查看整个月,而是只查看 2 周,从而加快速度(尽管它已经非常快了)。我使用 eomday 来获取该月的最后一天,这意味着我不必假设第一周的假期天数很少或其他任何事情。


编辑: 使用 datenum 将速度提高一半(C/O JohnAndrews):

function d = fbusdateAferWE( y, m )
    % Inputs: y = year, m = month
    % Outputs: day of the month, first business day after weekend

    % Create array of days for (first 2 weeks of) the given month
    dates = datenum(datetime(y,m,1)):datenum(datetime(y,m,eomday(y,m)))-14;        
    % Get the weekday numbers to find first Monday, 1 = Sunday
    dayNum = weekday( dates );         
    % Create the logical array to determine days from first Monday
    afterFirstWeekend = ( cumsum(dayNum==2) > 0 ).';         
    % Get first day which is afterFirstWeekend and a business day.
    d = find( afterFirstWeekend & isbusday( dates ), 1 );    
end