LoginSignup
0
0

More than 1 year has passed since last update.

Date Shifting in Ruby

Last updated at Posted at 2022-01-28

Rubyにおける二重山括弧「<<」「>>」についてのメモ。
(環境は Ruby 2.0.0 + Rails 4.2.4)

「<<」は文字列の場合は連結、配列の場合は追加となるが、
日付の場合、結論としては月単位の操作を行っていることがわかったが、
どういう理屈で以下の挙動をしているのかよくわからなかった。

ruby
require 'date'

now = Time.now
puts now
#=> 2022-01-28 12:43:10 +0900

# 「<< N」で Nヵ月前
puts Date.new(now.year, now.month,  1) << 2  #=> 2021-11-01
puts Date.new(now.year, now.month, -1) << 2  #=> 2021-11-30
puts Date.new(now.year, now.month, -1) << -1 #=> 2022-02-28

# 「>> N」で Nか月後
puts Date.new(now.year, now.month, -1) >> 2 #=> 2022-03-31
puts Date.new(now.year, now.month, -1) >> 3 #=> 2022-04-30

(追記)
ちゃんとリファレンスマニュアルを読もう。

以下引用。

class Date インスタンスメソッド

self << n -> Date

self より n ヶ月前の日付オブジェクトを返します。 n は数値でなければなりません。

require 'date'
Date.new(2001,2,3)  <<  1   #=> #<Date: 2001-01-03 ...>
Date.new(2001,2,3)  << -2   #=> #<Date: 2001-04-03 ...>

# 対応する月に同じ日が存在しない時は、代わりにその月の末日が使われます。
Date.new(2001,3,28) << 1   #=> #<Date: 2001-02-28 ...>
Date.new(2001,3,31) << 1   #=> #<Date: 2001-02-28 ...>

# このことは以下のように、もしかすると予期しない振る舞いをするかもしれません。
Date.new(2001,3,31) << 2         #=> #<Date: 2001-01-31 ...>
Date.new(2001,3,31) << 1 << 1    #=> #<Date: 2001-01-28 ...>

Date.new(2001,3,31) << 1 << -1   #=> #<Date: 2001-03-28 ...>
self >> n -> Date

self から n ヶ月後の日付オブジェクトを返します。 n は数値でなければなりません。

require 'date'
Date.new(2001,2,3)  >>  1   #=> #<Date: 2001-03-03 ...>
Date.new(2001,2,3)  >> -2   #=> #<Date: 2000-12-03 ...>

# 対応する月に同じ日が存在しない時は、代わりにその月の末日が使われます。
Date.new(2001,1,28) >> 1   #=> #<Date: 2001-02-28 ...>
Date.new(2001,1,31) >> 1   #=> #<Date: 2001-02-28 ...>

# このことは以下のように、もしかすると予期しない振る舞いをするかもしれません。
Date.new(2001,1,31) >> 2         #=> #<Date: 2001-03-31 ...>
Date.new(2001,1,31) >> 1 >> 1    #=> #<Date: 2001-03-28 ...>

Date.new(2001,1,31) >> 1 >> -1   #=> #<Date: 2001-01-28 ...>
0
0
1

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0