Project

General

Profile

Defect #29855 » 0002-Make-working_days-consistent-with-add_working_days-w.patch

Go MAEDA, 2026-10-14 10:18

View differences:

app/models/issue.rb
1414 1414
    (start_date && due_date) ? due_date - start_date : 0
1415 1415
  end
1416
  # Returns the duration in working days
1416
  # Returns the duration in working days, counted from the first working day
1417
  # on or after start_date in the same way as #reschedule_on does
1417 1418
  def working_duration
1418
    (start_date && due_date) ? working_days(start_date, due_date) : 0
1419
    (start_date && due_date) ? working_days(next_working_date(start_date), due_date) : 0
1419 1420
  end
1420 1421
  def soonest_start(reload=false)
lib/redmine/utils/date_calculation.rb
20 20
module Redmine
21 21
  module Utils
22 22
    module DateCalculation
23
      # Returns the number of working days between from and to
23
      # Returns the number of working days after from up to and including to,
24
      # so that add_working_days(from, working_days(from, to)) is the last
25
      # working day on or before to
26
      #
27
      # Example: when Saturday and Sunday are non-working days,
28
      # working_days(Sat 2012-10-20, Sun 2012-10-28) returns 5
29
      # (Mon 2012-10-22 to Fri 2012-10-26), and
30
      # add_working_days(Sat 2012-10-20, 5) returns Fri 2012-10-26
24 31
      def working_days(from, to)
25 32
        days = (to - from).to_i
26 33
        if days > 0
34
          # Count by whole weeks first. Any 7 consecutive days contain the
35
          # same number of working days, wherever the weeks start.
27 36
          weeks = days / 7
28 37
          result = weeks * (7 - non_working_week_days.size)
38
          # Remainder loop: check day by day the remaining days, starting
39
          # from the day after from
29 40
          days_left = days - weeks * 7
30 41
          start_cwday = from.cwday
31 42
          days_left.times do |i|
32
            unless non_working_week_days.include?(((start_cwday + i - 1) % 7) + 1)
43
            unless non_working_week_days.include?(((start_cwday + i) % 7) + 1)
33 44
              result += 1
34 45
            end
35 46
          end
36
          result - non_working_dates_count(from, to)
47
          result - non_working_dates_count(from + 1, to + 1)
37 48
        else
38 49
          0
39 50
        end
test/unit/issue_test.rb
2438 2438
      issue.reschedule_on '2012-10-13'.to_date
2439 2439
      assert_equal '2012-10-15'.to_date, issue.start_date
2440 2440
      assert_equal '2012-10-25'.to_date, issue.due_date
2441

  
2442
      # Starting on Saturday, from Monday 2012-10-15 to Friday 2012-10-19
2443
      issue = Issue.new(:start_date => '2012-10-13', :due_date => '2012-10-19')
2444
      issue.reschedule_on '2012-10-22'.to_date
2445
      assert_equal '2012-10-22'.to_date, issue.start_date
2446
      assert_equal '2012-10-26'.to_date, issue.due_date
2441 2447
    end
2442 2448
  end
test/unit/lib/redmine/utils/date_calculation_test.rb
35 35
  def test_working_days_with_non_working_week_days
36 36
    with_settings :non_working_week_days => %w(6 7) do
37
      assert_working_days 14, '2012-10-09', '2012-10-27'
37
      assert_working_days 13, '2012-10-09', '2012-10-27'
38 38
      assert_working_days  4, '2012-10-09', '2012-10-15'
39
      assert_working_days  4, '2012-10-09', '2012-10-14'
39
      assert_working_days  3, '2012-10-09', '2012-10-14'
40 40
      assert_working_days  3, '2012-10-09', '2012-10-12'
41 41
      assert_working_days  8, '2012-10-09', '2012-10-19'
42 42
      assert_working_days  8, '2012-10-11', '2012-10-23'
43
      assert_working_days  2, '2012-10-14', '2012-10-17'
44
      assert_working_days 11, '2012-10-14', '2012-10-30'
43
      assert_working_days  3, '2012-10-14', '2012-10-17'
44
      assert_working_days 12, '2012-10-14', '2012-10-30'
45
      # From Saturday and Sunday to Friday 2012-10-26
46
      assert_working_days  5, '2012-10-20', '2012-10-26'
47
      assert_working_days  5, '2012-10-21', '2012-10-26'
45 48
    end
46 49
  end
......
76 79
    # Registered on a non-working week day, should not be counted twice
77 80
    NonWorkingDate.create!(:date => '2012-10-13')
78 81
    with_settings :non_working_week_days => %w(6 7) do
79
      assert_working_days 13, '2012-10-09', '2012-10-27'
82
      assert_working_days 12, '2012-10-09', '2012-10-27'
80 83
      assert_working_days  1, '2012-10-09', '2012-10-11'
81
      assert_working_days  0, '2012-10-10', '2012-10-11'
84
      assert_working_days  1, '2012-10-10', '2012-10-11'
82 85
      assert_working_days  3, '2012-10-11', '2012-10-16'
83 86
    end
84 87
  end
(3-3/3)