【Ruby】Date、Time、Datetimeクラスの基本

- 日時、時間を扱える。Datetimeは両方、Dateは日付、Timeは時間を管理。
- うるう年、1ヶ月ごとの日数、曜日などの管理も可能。
- Rails独自の便利なメソッドも用意されてる。より可読性、安全性の高い。

# Date クラス(日付)
- 日付を扱うクラス。
- `require "date"` が必要。

```rb:例)Dateクラスの使い方
require "date"   # 外部ファイルを参照し、クラスを取得するので、必須

# today メソッド
  today = Date.today           # 今日
  today - 1                    # 昨日
  today.year                   # 年
  today.mon                    # 月
  today.mday                   # 日
  today.wday                   # 曜日
  today.strftime('%a')         # "Sat"

# 日付が存在するか？
Date.valid_date?(2020, 9, 5)   # true
Date.valid_date?(2020, 9, 31)  # false
Date::exist?(2001, 1, 31)      # 2451941(ユリウス日を返す)
Date::exist?(2001, 1, 32)      # false

# Date::new1メソッド( ユリウス日 )
  # ユリウス日: 紀元前4713年1月1日(ユリウス暦)正午(グリニッジ平均時) を暦元とした時の経過日数
julius = Date::exist?(2001, 1, 31) # 経過日数(2451941)
Date::new1(julius).to_s      # "2001-01-31"

# eap?メソッド( うるう年か? )
Date.new(2000).leap?   # true
Date.new(2001).leap?   # false

# parse メソッド
date = Date.parse("2020-09-05")  # 引数をもとにDateオブジェクトを作成
Date.parse(str_time).to_time     # Date型 → Time型 に変換 (※ 時刻は、00:00:00 になる)

# new メソッド (クラスのインスタンス作成に使う)
  input = Date.new(2020, 9, 5)   # 引数をもとにDateオブジェクトを作成
  input += 10                    # 10日後を取得
  input - date                   # 10
  Date.new(2020, 9, -1)          # 第3引数を負にすると、末日から数える(※ -1 が末日)。
```

# Time クラス(日時)
- UNIXタイムで日時を扱うクラス
- `require "time"` が必要

```rb:例)Timeクラスの使い方
require "time"

now = Time.current               # 現在時刻
Time.mktime(2000, 1, 1).yday     # 2000/1/1からの日数
Time.parse(str_time).to_date     # Time型 → Date型 に変換

today = Time.now()               # 現在時刻( 2020-06-17 19:30:02 +0000 )
  today.year                     # 年(2020)
  today.month                    # 月(6）
  today.day                      # 日(17）

  now.yesterday                # 昨日
  now.tomorrow                 # 翌日
  now.ago(3.days)              # ●日前
  now.prev_day(3)
  now.since(3.days)            # ●日後
  now.next_day(3)

  now.beginning_of_week        # 今週の最初
  now.end_of_week              # 今週の末
  now.prev_week(:monday)       # 先週の月曜日
  now.next_week(:monday)       # 翌週の月曜日

  now.prev_month               # 前月
  now.next_month               # 翌月
  now.ago(3.month)             # ●ヶ月前
  now.prev_month(3)
  now.since(3.month)           # ●ヶ月後
  now.next_month(3)
  now.beginning_of_month       # 月初
  now.end_of_month             # 月末

  now.prev_year                # 前年
  now.next_year                # 翌年
  now.ago(3.years)             # ●年前
  now.prev_year(3)
  now.since(3.years)           # ●年後
  now.next_year(3)

# parse メソッド
Time.parse("2020-09-05 12:22:50")
Time.parse("2020/09/05 12:22:50")
Time.parse("2020-09/05 12:22:50")
Time.parse("20200905 122250")
Time.parse("20200905122250")
Time.parse("2020/09/05 12")         # 2020-09-05 12:00:00 +0900
Time.parse("2020/09/05 12:22")      # 2020-09-05 12:22:00 +0900
  # 変更も可能
  Time.parse("2020.06.17 12:00:00") do |year|
    if year < 100
      if year >= 69
        year + 1900
      else
        year + 2000
      end
      year
    end
  end

# gmメソッド、utcメソッド(協定世界時)
Time.gm(2001, 5, 20, 23, 59, 59)    # Sun May 20 23:59:59 UTC 2001
# localメソッド、mktimeメソッド(ローカルタイム)
Time.local(2001, 5, 20, 23, 59, 59) # Sun May 20 23:59:59 JST 2001

# 文字列(14桁)に変換
now.to_s                        # '20200905122250'
now.insert(8, ' ')              # '20200905 122250' (8桁目でスペースを入れる)
```


# DateTimeクラス(日時)
- 日付と時刻を扱うクラス(Dateのサブクラス)。
- Dateクラスと同じメソッドが使える。時刻まで扱える。
- `require "date"` が必要。

```rb:例)DateTimeクラスの使い方
require "date"

date = DateTime.now    # 今の日時(2020-09-05 17:08:37 +0900)
DateTime.now - 1       # 昨日

input = DateTime.new(2020, 9, 5, 17, 8, 37)
date = DateTime.parse('2020-09-05T17:08:37')
  date += 10
  date - input                 # 10
  date.year                    # 2020
  date.strftime('%a')          # "Sat"
  date.strftime("%Y年%m月%d日") # 2020年9月5日
```

# strftime メソッド
- 取得/表示フォーマットの指定。

|表記|意味|例|
|:--|:--|:--|
|%A|曜日|Sunday,Monday,..|
|%a|曜日(省略名)|Sun,Mon,..|
|%B|月|January,February,..|
|%b|月(省略名)|Jan, Feb,..|
|%c|日付と時刻||
|%d|日|01-31|
|%H|時間(24h)|00-23|
|%I|時間(12h)|01-12|
|%j|年の通算日|001-366|
|%M|分|00-59|
|%m|月(数字)|01-12|
|%p|午前 or 午後|AM,PM|
|%S|秒|00-60(※60はうるう秒)|
|%U|週(数字)※日曜始まり|00-53|
|%W|週(数字)※月曜始まり|00-53|
|%w|曜日(数字)※日曜日が0|0-6|
|%X|時刻|09|
|%x|日付|09/20/20|
|%Y|西暦|2020|
|%y|西暦(下2桁)|00-99|
|%Z|タイムゾーン|JST|
|%%|パーセント文字||