添付ライブラリ: Date/DateTime

Siverの出題範囲で既にTimeクラスを扱っているが、DateTimeクラスはDateクラスを継承して拡張するとともに、Timeクラスの拡張も提供している。

DateもDateTimeもユリウス日からの経過日数をRationalで保持し、その小数部で時間を表している。Rational同士の引き算はたとえ答えが1であったとしてもIntegerではなくRational(1を分子とする小数)で返ってくる点に注意する。

require "date"

puts Date.new(2019,11,24) - Date.new(1996,8,1) # 8515/1
puts ((Date.new(2019,11,24) - Date.new(1996,7,19))/365).to_i # 23

ユニークな機能として<<>>で一か月単位の日操作ができる。

require "date"
puts Date.new(2019,11,24) >> 4 # "2020-03-24"

Date.parse / Date.strptime

この2つのクラスメソッドは文字列からDateオブジェクトを生成する。 2番目の引数はtrueにした場合は2桁表示を4桁表示にするオプションで、69よりも小さい場合は2000年代として、69以上であれば1900年代として処理される。

require "date"

puts Date.parse("2019-11-24")    # 2019-11-24
puts Date.parse("69-01-01",true) # 1969-01-01
puts Date.parse("68-12-11",true) # 2068-12-11
puts Date.parse("1996/8/4")      # 1996-08-04
puts Date.parse("1996年8月5日")  # ダメ
puts Date.parse("1996,8,10")     # ダメ

strptimeを使えば上の例でダメだったようなフォーマットでも、ちゃんとフォーマットを教えてやればうまくいく。

ちなみに```strftime````はフォーマットを指定した「文字列化」処理。pがparseでfがfortizeなので覚えておく。

puts Date.strptime("1996年8月5日", "%Y年%m月%d日")# 1996-08-05

この他にもいろいろメソッドがある。

puts Date.today      # 2019-11-24
puts Date.today.mday # 24
puts Date.today.month# 11

puts Date.today.next # 2019-11-25
puts Date.today.succ # 2019-11-25(alias)

指定した日付づつ日付を引いていくOR足していくメソッドであるstep(limit, step){ |date| } の他、それを一日づつに固定したdowntouptoがある。

Date.parse("2019-11-23").step(Date.parse("2020-4-1"),7){ |date|
  # 2019-11-23は土曜日なので、来年の4月までの土日の数を数えてみる。
  puts date 
  puts date + 1
}
# 2019-11-23
# 2019-11-24
# 2019-11-30
# 2019-12-01
# 2019-12-07
# 2019-12-08
# 2019-12-14
# 2019-12-15
# 2019-12-21
# 2019-12-22
# 2019-12-28
# 2019-12-29
# ....

DateTimeはDateクラスを継承し、さらに時間の保持もサポートしている。 年、月、日の後ろに更に「時間、分、秒、時差」を指定する。時差はRational(X, 24)で指定するか"+09:00"のように指定する。

puts DateTime.new(2019,11,24,15,4,36,Rational(9,24)) # 2019-11-24T15:04:36+09:00
puts DateTime.new(2019,11,24,15,4,36,"+09:00") # 2019-11-24T15:04:36+09:00

obj = DateTime.new(2019,11,24,15,4,36,Rational(9,24))
puts obj.hour   # 15
puts obj.sec    # 36
puts obj.zone   # +09:00
puts obj.offset # 3/8

offestはrationalの形で返されるが、rationalは必ず約分済の値が返ってくるのでややわかりにくい表記になる。