Как получить первый рабочий день в новом месяце после выходных? - PullRequest
0 голосов
/ 07 декабря 2018

Как я могу с умом получить первый рабочий день месяца после выходных?

Чтобы получить первый рабочий день месяца (с учетом dateInput), мы можем сделать:

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

Например, для ноября использование вышеуказанной функции вернет четверг 1 ноября в качестве первого рабочего дня.Однако первый рабочий день месяца после первых выходных - понедельник 5 ноября. Как я могу получить эту последнюю дату?

enter image description here

Примечания:

  • Выходные не обязательно должны быть в одном и том же месяце.
  • Если понедельник не является рабочим днем, я хотел бы, чтобы он возвратил следующийрабочий день

Ответы [ 2 ]

0 голосов
/ 07 декабря 2018

Эта функция сделает свое дело.Вот логика:

  • Создание массива datetime для всех дней в данном месяце.
  • Получение номеров дней.
  • Создание логического массива, true изс первого понедельника (то есть после первых выходных, учитывая, что последний день предыдущего месяца является воскресным).
  • Создайте еще один логический массив, используя 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
0 голосов
/ 07 декабря 2018

Я бы добавил что-то вроде этого после вашего заявления:

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

Это работает, потому что «день недели» вернет число от 1 (воскресенье) до 7 (суббота).

Функция fbusdate () никогда не будет возвращать 1 или 7, поэтому мы можем игнорировать эти случаи.

Если weekday (fbusdate ()) == 2, первое происходит в понедельник, а переменная firstBusdayMonth не нужнаподлежит изменению.

Если день недели (firstBusdayMonth) возвращается между 2 и 6, нам нужно перейти к следующей неделе, поэтому мы вычитаем значение дня недели из 10, чтобы найти следующий понедельник.

Возможно, это не самое элегантное решение 1013 *, но оно должно работать.

...