Friday, May 23, 2008

Ruby Patesuke

パテ助の期間計算プログラムをRubyで作った。
  • 手続き期間(Deadline)、権利期間(ExpireDay)に対応
  • 春分の日、秋分の日、ハッピーマンデー法に対応

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

71

72

73

74

75

76

77

78

79

80

81

82

83

84

85

86

87

88

89

90

91

92

93

94

95

96

97

98

99

100

101

102

103

104

105

106

107

108

109

110

111

112

113

114

115

116

117

118

119

120

121

122

123

124

125

126

127

128

129

130

131

132

require "date"

require "active_support"


class Date

  alias cwday_old cwday

  HOLIDAYS = ['1/1','2/11','4/29','5/3','5/4','5/5','7/20',

  '9/15','9/22','11/3','11/23','12/23']

  IRR_HOLIDAYS = ['shunbun','shuubun','seijin','umi','keiro','taiiku']

  JPO_HOLIDAYS = ['12/29','12/30','12/31','1/02','1/03']


  def deadline(term)

    dl = self + term

    while dl.cwday > 5 #postpone till first weekday

      dl += 1

    end

    dl

  end


  def expire_day(term)

    self + term

  end


  # 1-5:weekdays, 6:sat, 7:sun, 8:holiday, 9:jpo holiday

  def cwday

    @irr_holidays = irr_days(IRR_HOLIDAYS, self.year)

    @holidays = (HOLIDAYS + @irr_holidays).map do |date|

      date.split('/').map { |e| e.to_i }

    end

    @jpo_holidays = JPO_HOLIDAYS.map do |date|

      date.split('/').map { |e| e.to_i }

    end


    if @holidays.include?([self.mon, self.day])

      8

    elsif @jpo_holidays.include?([self.mon, self.day])

      9

    else

      cwday_old

    end


  end


  private

  def irr_days(irr_days, year)

    base1 = 0.242194 * (year - 1980) - ((year - 1983)/4)

    base2 = 0.242194 * (year - 1980) - ((year - 1980)/4)

    irr_days.map do |date|

      monday = 0

      case date

      when 'shunbun'

        case year

        when 1851..1899

          day = 19.8277 + base1

        when 1900..1979

          day = 20.8357 + base1

        when 1980..2099

          day = 20.8431 + base2

        when 2100..2150

          day = 21.8510 + base2

        end

        "3/#{day.to_i}"

      when 'shuubun'

        case year

        when 1851..1899

          day = 22.2588 + base1

        when 1900..1979

          day = 23.2588 + base1

        when 1980..2099

          day = 23.2488 + base2

        when 2100..2150

          day = 24.2488 + base2

        end

        "9/#{day.to_i}"

      when 'seijin'

        if year > 1999

          (8..14).to_a.each do |day|

            d = Date.new(year,1,day)

            monday = day if d.cwday_old == 1

          end

          "1/#{monday}"

        else

          '1/15'

        end

      when 'umi'

        if year > 2002

          (15..21).to_a.each do |day|

            d = Date.new(year,7,day)

            monday = day if d.cwday_old == 1

          end

          "7/#{monday}"

        else

          '7/20'

        end

      when 'keiro'

        if year > 2002

          (15..21).to_a.each do |day|

            d = Date.new(year,9,day)

            monday = day if d.cwday_old == 1

          end

          "9/#{monday}"

        else

          '9/15'

        end

      when 'taiiku'

        if year > 1999

          (8..14).to_a.each do |day|

            d = Date.new(year,10,day)

            monday = day if d.cwday_old == 1

          end

          "10/#{monday}"

        else

          '10/10'

        end

      end

    end

  end

end


if __FILE__ == $0

  days = [[1998,1,15],[2008,7,21], [2008,9,15], [2008,10,13],[2120,3,21]]

  days.each do |day|

    d = Date.new(day[0],day[1],day[2])

    print d.strftime("%Y/%m/%d %a")

    print " new:#{d.cwday}, old:#{d.cwday_old}\n"

    f = 1.year

    dl = d.deadline(f)

    ex = d.expire_day(f)

    print "deadine is #{dl}. #{dl.cwday}\n"

    print "expire date is #{ex}. #{ex.cwday}\n"

    puts ""

  end

end

No comments: