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

时间:2018-12-07 13:42:49

标签: matlab datetime weekday

我如何以一种聪明的方式在周末之后获得一个月的第一个工作日?

要获取每月的第一个工作日(给定dateInput),我们可以执行以下操作:

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

例如,对于11月,使用上述功能将返回11月1日(星期四)作为第一个工作日。但是,第一个周末之后的一个月的第一个工作日是11月5日(星期一)。

enter image description here

注意:

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

2 个答案:

答案 0 :(得分:3)

此功能可以解决问题。这是逻辑:

  • 为给定月份中的所有日期创建日期时间数组。
  • 获取日期。
  • 创建一个逻辑数组,从第一个星期一开始为真(因此,第一个周末之后,占上个月的最后一天为星期日)。
  • 使用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

您可能不需要查看整个月的时间,而是说仅仅两个星期,就可以加快速度(尽管它已经相当快了)。我使用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

答案 1 :(得分:-1)

我会在您的发言后添加以下内容:

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

之所以可行,是因为“工作日”将返回介于1(星期日)和7(星期六)之间的数字。

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

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

如果工作日(firstBusdayMonth)返回2到6之间,我们需要跳到下一周,所以我们从10中减去工作日的值以找到下一个星期一。

这可能不是最优雅的解决方案,但应该可以。