Я не могу получить 15-й рабочий день в рубине - PullRequest
2 голосов
/ 24 марта 2019

Я не могу получить следующий 15-й день, но не рабочий день.

DateTime.now.next_day(+15).strftime('%d %^B %Y')

как я могу получить следующий 15-й рабочий день?

Ответы [ 6 ]

1 голос
/ 31 марта 2019

Итак, вы хотите добавить 15 рабочих дней с текущей даты.Вы можете использовать ответы iGian или Aleksei vanilla ruby ​​или использовать business_time gem:

15.business_days.from_now
1 голос
/ 24 марта 2019
15.times.reduce(Date.civil 2019, 03, 24) do |acc, _|
  begin
    acc += 1
  end while [0, 6].include? acc.wday
  acc
end
#⇒ #<Date: 2019-04-12 ((2458586j,0s,0n),+0s,2299161j)>
1 голос
/ 24 марта 2019

Вы просто добавляете 15 дней к текущей дате.Вам нужно настроить дату:

date = DateTime.now

if (date.mday > 15)
  date = date.next_month
end

date = date.next_day(15 - date.mday)

Где это будет 15-го числа следующего месяца, если оно уже прошло 15-го числа текущего месяца.

Теперь это может бытьрасширенный для перечисления:

def each_mday(mday, from: nil)
  from ||= DateTime.now

  Enumerator.new do |y|
    loop do
      if (from.mday > mday)
        from = from.next_month
      end

      from = from.next_day(mday - from.mday)

      y << from

      from += 1
    end
  end
end

, что позволяет найти первый день, соответствующий определенным критериям, например, будний день:

each_mday(15, from: Date.parse('2019-06-14')).find { |d| (1..5).include?(d.wday) }

Где это возвращается 15 июля, как июнь15-е число - выходные.

Аргумент from необязателен, но полезен для тестирования подобных случаев, чтобы убедиться, что он работает правильно.

0 голосов
/ 24 марта 2019

Я предполагаю, что, учитывая начальную дату, ds (объект Date) и положительное целое число n, проблема заключается в определении более поздней даты, dt, такой, что между ds+1 иdt включительно, там n дней недели.

require 'date'

def given_date_plus_week_days(dt, week_days)
  wday = dt.wday
  weeks, days = (week_days + {0=>4, 6=>4}.fetch(wday, wday-1)).divmod(5)
  dt - (wday.zero? ? 6 : (wday - 1)) + 7*weeks + days
end

Переменной wday назначается день недели для даты начала, dt.Дата начала переносится назад на предыдущий понедельник, если только она не выпадает на понедельник, и в этом случае она не изменяется.Это отражено в выражении

wday.zero? ? 6 : (wday - 1)

, которое вычитается из dt.Количество дней недели соответственно скорректировано до

week_days + { 0=>4, 6=>4 }.fetch(wday, wday-1)

Остальные расчеты просты.

def display(start_str, week_days)    
  start = Date.parse(start_str)
  7.times.map { |i| start + i }.each do |ds|
    de = given_date_plus_week_days(ds, week_days)
    puts "#{ds.strftime("%a, %b %d, %Y")} + #{week_days} -> #{de.strftime("%a, %b %d, %Y")}"   
  end
end

display("April 8", 15)
Mon, Apr 08, 2019 + 15 -> Mon, Apr 29, 2019
Tue, Apr 09, 2019 + 15 -> Tue, Apr 30, 2019
Wed, Apr 10, 2019 + 15 -> Wed, May 01, 2019
Thu, Apr 11, 2019 + 15 -> Thu, May 02, 2019
Fri, Apr 12, 2019 + 15 -> Fri, May 03, 2019
Sat, Apr 13, 2019 + 15 -> Fri, May 03, 2019
Sun, Apr 14, 2019 + 15 -> Fri, May 03, 2019

display("April 8", 17)
Mon, Apr 08, 2019 + 17 -> Wed, May 01, 2019
Tue, Apr 09, 2019 + 17 -> Thu, May 02, 2019
Wed, Apr 10, 2019 + 17 -> Fri, May 03, 2019
Thu, Apr 11, 2019 + 17 -> Mon, May 06, 2019
Fri, Apr 12, 2019 + 17 -> Tue, May 07, 2019
Sat, Apr 13, 2019 + 17 -> Tue, May 07, 2019
Sun, Apr 14, 2019 + 17 -> Tue, May 07, 2019
0 голосов
/ 24 марта 2019

Если я получу точку, вам нужно найти 15-й день после указанной даты, пропуская выходные.

Один из возможных вариантов - определить хеш skipping_weekend следующим образом, учитывая Date.html # wday :

skip_weekend = { 6 => 2, 0 => 1}
skip_weekend.default = 0

Тогда:

next15 = DateTime.now.next_day(15)
next15_working = next15.next_day(skip_weekend[next15.wday]).strftime('%d %B %Y')

Теперь, если next15 выпадает на рабочий день, next15_working - это тот же день (по умолчанию хеш-код 0), в противном случае он пропускает 2 дня, если суббота (день 6-й недели, хеш-код отображается на 2) или 1 день, если воскресенье (день 0-й недели, хэш отображается на 1)

0 голосов
/ 24 марта 2019

Если я правильно понял, вы хотите получить в следующий понедельник, если вы нажмете субботу или воскресенье.Поскольку wday дает вам 0 для Солнца и 6 для Сб, вы можете использовать его в качестве условия для добавления дней к понедельнику.

def date_add_next_week_day(days)
  date = (Date.today + days)
  date += 1 if date.wday == 6
  date += 1 if date.wday == 0
  date
end

date_add_next_week_day(15).strftime('%d %^B %Y')
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...