Rubyで法律に従った暦による期間計算(日割りにならない1ヵ月を求める)
以前、法律に従った暦上の計算方法を記事にし、Javaでも同様の記事を作成しました。
当記事ではRubyで法律に従った暦による期間の計算を求める方法を記します。
環境
- Ruby
- 3.0.2p107
- Rails
- 6.0.3.7
- RSpec
対応
テストデータとロジックに関してはJavaと同じです。
Rubyらしい書き方をしているだけで、新規の内容はありません。テストコードもParameterizedTestを使用していますが、あまり面白いことはしていないので特に記載しません。
beginning_of_month?のような、月初、月末であることがわかるメソッドがあればもうちょっと綺麗に書けるとは思うのですが…。そういうメソッドが生えていない以上、泥臭い書き方なのは仕方ないです。
# contractDate(契約日):datetime
# expireDate(解約日):datetime
class Contract
attr_reader :contractDate
attr_reader :expireDate
def initialize(contractDate, expireDate)
@contractDate = contractDate
@expireDate = expireDate
end
##
# 解約可能か
# 日割とはならない契約日と解約日の関係であること
#
# @see https://nainaistar.hatenablog.com/entry/2021/05/02/120000
def canExpire?
return true if canExpireByStartOfMonth?
return true if canExpireByHasEndOfMonth?
canExpireByHasNotEndOfMonth?
end
private
##
# 月の初日から起算する場合は、最終月の末日
#
def canExpireByStartOfMonth?
return expireDate.next_day(1).day == 1 if contractDate.day == 1
false
end
##
# 月の途中から起算し,最終月に応当日のある場合は、最終月の応当日の前日
# -1日すると、月を跨ぐ可能性があるのでNG
#
def canExpireByHasEndOfMonth?
contractDate.day == expireDate.next_day(1).day
end
##
# 月の途中から起算し,最終月に応当日のない場合は、最終月の末日
#
def canExpireByHasNotEndOfMonth?
return expireDate.next_day(1).day == 1 if contractDate.day > expireDate.day
false
end
end
ソースコード
- https://github.com/hirotoKirimaru/ror-practice/blob/286e5af3cc376caf90992ce8a4f8028f796bbf5b/sandbox/app/models/contract.rb
- https://github.com/hirotoKirimaru/ror-practice/blob/286e5af3cc376caf90992ce8a4f8028f796bbf5b/sandbox/spec/models/contract_spec.rb
終わりに
Javaよりも書きやすいですね。ただ、後置ifを多用してしまっているので、ちょっとわかりづらくなっている気もします。
Publicメソッドの後置ifはともかく、Privateメソッドの後置ifはやめておいた方がいいかもしれません。
この記事がお役に立ちましたら、各種SNSでのシェアや、今後も情報発信しますのでフォローよろしくお願いします。