Rubyで時刻を扱うには「Time」クラスを使用します。「Time」クラスを使うと、現在時刻の取得や特定の時刻を設定したりできます。この記事では、Rubyの「Time」クラスの使い方を紹介していきます。
Timeクラス
Rubyで日時を扱うクラスには、大きく「DateTime」と「Time」が存在します。
「DateTime」クラスは、日付のみを扱う「Date」クラスから派生したクラスで、日付と時刻の両方を扱うときに利用します。
一方で「Time」クラスは時刻を扱うクラスで、内部的には、起算日(協定世界時(UTC))の1970年1月1日午前0時からの経過秒数で値を保持しています。
「Time」クラスを使用すると、現在時刻の取得をしたり、任意の時刻の設定、書式を指定して時刻を12:10:00などのような形式で文字列に変換したりできます。
Timeオブジェクトを作成して現在時刻を取得
「Time」クラスのオブジェクトを作成し、現在時刻を取得する場合はTime#newまたはTime.nowメソッドを使用します。どちらのメソッドも現在時刻の「Time」オブジェクトを作成するという点では同じです。
# Time#newで現在時刻を取得
t = Time.new
#Time.nowで現在時刻を取得
t = Time.now
現在時刻を取得して、コンソールにそれを出力する簡単なサンプルコードを見ていきましょう。
t = Time.new
puts "Time#new: #{t}"
t = Time.now
puts "Time#now: #{t}"
Time#new: 2021-05-14 00:16:19 +0000
Time#now: 2021-05-14 00:16:19 +0000
任意の時刻でTimeオブジェクトを作成する
任意の時刻を指定して「Time」オブジェクトを作成する場合は、Time#localまたはTime#mktimeメソッドを使用します。これらのメソッドはローカルのタイムゾーンで「Time」クラスのオブジェクトを作ります。
Time#localおよびTime#mktimeメソッドの構文は次の通りです。
local(year, mon = 1, day = 1, hour = 0, min = 0, sec = 0, usec = 0) -> Time
mktime(year, mon = 1, day = 1, hour = 0, min = 0, sec = 0, usec = 0) -> Time
先頭の年(year)の指定のみが必須で、それ以外の月(mon)や日(day)などの引数は省略できます。引数を省略した場合は、上に書いてある通りのデフォルト値が指定されることになります。
では、Time#localメソッドで任意の時刻で「Time」オブジェクトを作成するサンプルコードを確認してみましょう。
#「2021/5/20 9:33:45.000」で Timeオブジェクトを作成
t1 = Time.local(2021, 5, 20, 9, 33, 45, 0)
p t1
2021-05-20 09:33:45 +0900
このように、タイムゾーンがJST(日本標準時)のPCで上記のコードを実行すると、その端末に合わせたタイムゾーンの「Time」オブジェクトが取得できます。
Time#localには、タイムゾーンを引数が引数にある、次の構文のメソッドもありますが、公式APIガイドにも記載がある通り、ここでタイムゾーンを指定しても無視されるため、使用することはないでしょう。
local(sec, min, hour, mday, mon, year, wday, yday, isdst, zone)
Timeクラスの各値を取り出す
「Time」オブジェクトのプロパティから、年や月などの各フィールド値を取得できます。
t = Time.now #=> 2021/5/14 13:52:47
puts "[年] #{t.year}"
puts "[月] #{t.month}"
puts "[日] #{t.day}"
puts "[時] #{t.hour}"
puts "[分] #{t.min}"
puts "[秒] #{t.sec}"
puts "[マイクロ秒] #{t.usec}"
puts "[曜日(0:日〜6:土)] #{t.wday}"
puts "[タイムゾーン] #{t.zone}"
[年] 2021
[月] 5
[日] 14
[時] 13
[分] 52
[秒] 47
[マイクロ秒] 238825
[曜日(0:日〜6:土)] 5
[タイムゾーン] UTC
日付・時間の加減算
「Time」クラスのオブジェクトに対して日付・時刻の加減算を行います。
冒頭でも述べた通り、「Time」クラスは協定世界時(UTC)の1970年1月1日午前0時からの経過秒数で値を保持しており、内部的には時間を秒単位の数値で管理しています。そのため「Time」オブジェクトに対して1を加算すると時間が1秒加算され、1を引けば1秒減算といった具合になります。
いくつか、日付が時刻を加減算するサンプルコードを見てみましょう。
10秒加算(減算)
t = Time.now
puts t
puts t + 10 #10秒加算
puts t - 10 #10秒減算
2021-05-14 23:10:26 +0900
2021-05-14 23:10:36 +0900
2021-05-14 23:10:16 +0900
1時間加算(減算)
t = Time.now
puts t
#60秒×60分×1=1時間
puts t + 60*60*1 #1時間加算
puts t - 60*60*1 #1時間減算
2021-05-14 23:13:20 +0900
2021-05-14 23:13:30 +0900
2021-05-14 23:13:10 +0900
Timeクラスを書式指定して文字列化
Time#strftimeメソッドを使って、「Time」オブジェクトの内容を書式を指定して文字列化します。
次のコードはTime#nowメソッドで取得した時間を、HH:MM形式の文字列にフォーマットしています。
t = Time.now
puts t.strftime("現在時刻:%H:%M")
現在時刻:23:17
「Time」クラスという名前ではありますが、内部的な値は1970年1月1日午前0時からの経過秒数であるため、strftimeで日付の情報も文字列として出力できます。
t = Time.now
puts t.strftime("現在日付:%Y/%m/%d")
現在日付:2021/05/14
format文字列
strftimeメソッドで format文字列は、前のサンプルコードで使ったもの以外にも、次の表に示す文字列が使用できます。
format文字列 | 説明 | 出力例 |
---|---|---|
%A | 曜日名 | Sunday, Monday |
%a | 曜日省略名 | Sun, Mon |
%B | 月の名前 | January, February |
%b | 月の省略名 | Jan, Feb |
%c | 日付と時刻 | Thu Feb 4 00:15:53 2021 |
%d | 日 | 01-31 |
%H | 24時間制の時 | 00-23 |
%I | 12時間制の時 | 01-12 |
%j | 年中の通算日 | 001-366 |
%M | 分 | 00-59 |
%m | 月(ゼロ埋め) | 01-12 |
%p | 午前/午後 | AM,PM |
%S | 秒 | 00-59 |
%U | 1/1以降の最初の日曜日が第1週とした週の数 | 00-53 |
%W | 1/1以降の最初の月曜日が第1週とした週の数 | 00-53 |
%w | 曜日を表す数字。 | 0-6 |
%X | 時刻 | 00:00:00 |
%x | 日付 | 02/04/21 |
%Y | 西暦の年 | 2021 |
%y | 西暦の年(2桁) | 21 |
%Z | タイムゾーン | +00:00 |
さいごに
Rubyで時刻を扱う「Time」クラスの使用方法を紹介してきました。
日付や時刻の情報は、アプリの種類に限らず、ほとんどのシステム開発で必ずといっていいほど使うでしょう。この機会に是非、Rubyの時刻の扱いに慣れておきましょう。
Time#newおよびTime.nowメソッドは、どちらも現在時刻を取得し機能的にも差異はありませんが、Time#nowの方が現在時刻を取得すると意味が通じやすいため、基本的には現在時刻の取得=Time#nowを使っていたほうがよいでしょう。