以前、法律に従った暦上の計算方法を記事にし、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でのシェアや、今後も情報発信しますのでフォローよろしくお願いします。