#日付の比較備忘録
##投稿理由
日付の比較を行う際、毎回調べてしまっているので備忘録的に記載。
不等号の比較の書き方には慣れが必要で、特に日付関係ではバグを生みやすい印象があるため。
##内容一覧
###過去の日時
Post.where("published_at < ?", Date.current)
###現在の日時
Post.where(published_at: Date.current)
###未来の日時
Post.where("published_at > ?", Date.current)
####補足
「予約投稿機能」「使用制限日時」といった内容に対して利用されるかと思います。
###登録から1日以内
Post.where("published_at < ?", Date.current.yesterday)
###登録から1日
Post.where(published_at: Date.current.yesterday)
###登録から1日以降
Post.where("published_at > ?", Date.current.yesterday)
####補足
「登録から2週間無料」、「登録から1週間放置されたタスクに対して担当者に連絡」といった仕様があった際に利用されるかと思います。
昨日意外の場合は、[yesterday]を「tomorrow、X.days.ago、X.days.since」等に変更すれば利用可能です。
daysを「weeks,months,years」にすることも可能です。
#yesterday
Post.where(published_at: Date.current.yesterday)
SELECT 'posts'.* FROM 'posts' WHERE 'posts'.'published_at' = '2018-03-15'
#days_ago(1)
Post.where(published_at: Date.current.days_ago(1))
SELECT 'posts'.* FROM 'posts' WHERE 'posts'.'published_at' = '2018-03-15'
#ago(1.days) 時間も見るので注意
Post.where(published_at: Date.current.ago(1.days))
SELECT 'posts'.* FROM 'posts' WHERE 'posts'.'published_at' = '2018-03-15 00:00:00'
###来月1日以前
d = Date.current.beginning_of_month.next_month;
Post.where("published_at < ?", d)
###来月1日
d = Date.current.beginning_of_month.next_month;
Post.where(published_at: d)
###来月1日以降
d = Date.current.beginning_of_month.next_month;
Post.where("published_at > ?", d)
####補足
「月初からのキャンペーン」、「登録月は無料」といった仕様があった際に利用されるかと思います。
今月頭(beginning_of_month)の次の月(next_month)で来月の月初を指定しています。
来月末は
Date.current.end_of_month.prev_month
固定の日付の際は、
d = Date.new(2018, 12, 31)
Post.where("published_at > ?", d)
の様になります。
###A日から、B日の間
#A日から、B日の間
a = DateTime.new(2018, 11, 1, 00, 00, 00)
b = DateTime.new(2018, 12, 31, 23, 59, 59)
Post.where("published_at >= ?", a).where("published_at <= ?", b)
####補足
注意点としまして日時の比較で「beetween」は使わないで、whereを2つかけた方が良いということです。
それはdatetime型に対して使用をした際、
2018-11-01〜2018-12-31
とした時に、対象日付が、
2018-11-01 00:00:00 〜 2018-12-31 00:00:00
なのか
2018-11-01 00:00:00 〜 2018-12-31 23:59:59
なのかがひと目ではわからないからです。
これは他の比較でも起こりうることですが、DateTimeに対しDateの指定だけで比較を行う際は注意が必要です。
この指定は、「今期・来季のレポート」、「施策A期間と、施策B期間のデータ比較」といったケースでの利用が考えられます。
###あと何日?
time = Time.current
target_date = Time.mktime(2018, 12, 31, 0, 0, 0)
date_count = (target_date- time)/(60*60*24).truncate
date_count.truncate
単位が day の場合のみの話ですが、Date どうしの引き算で実現できます (@negito6 さんのコメントより)
[3] pry(main)> target_date.to_date - time.to_date
=> (291/1)
[4] pry(main)> (target_date.to_date - time.to_date).to_i
=> 291
####補足
「無料期間の残り日数」、「年末・リリース日」と言ったケースでしょうか、あまり利用頻度は高くないかと思います。
また、これは、残り「何ヶ月と何日」と出してほしい。といった仕様に変更される可能性もございます。
###参考記事
2017年まであと何日?rake taskで書いてみた - Qiita
[Ruby入門] 14. 日付と時刻を扱う(全パターン網羅) - Qiita