文字列をTimeオブジェクトに変換する
ボート競技(レガッタ)はスピードを競う競技。
なので情報の中でもタイムは特に気にするところ。
タイム差をもとめるには独特の計算が必要になる。頭の中で無意識にこなしてしまうけれど、計算式であらわそうとすればけっこう大変だ。
RubyのTimeオブジェクトならば-
メソッドでタイム差を計算できるし、 <
、>
メソッドでタイムの比較もできる。
今回はTimeオブジェクトのつくりかたを試す。
目次
任意の時刻をつくる
Timeクラスのlocalメソッド
RbuyにはTimeクラスが組み込まれている。
Timeクラスのlocalメソッドを使って任意の時刻をつくることができる。
書式は次のとおり。
Time.local(年,月,日,時,分,秒,コンマ秒)
年から秒まで順に全て記入する必要がある。
コンマ秒は任意。
TimeクラスのWebページ
Rubyリファレンスマニュアル
組み込みライブラリ Timeクラス
https://docs.ruby-lang.org/ja/latest/class/Time.html
timeライブラリのparseメソッド
timeライブラリはTimeクラスを拡張するライブラリ。
標準添付ライブラリなので読み込むだけで使える。
timeライブラリを読み込むと、文字列をTimeオブジェクトに変換するparseメソッドが使えるようになる。
parseメソッドの書式は次のとおり。
require 'time' Time.parse("年-月-日 時:分:秒.コンマ秒")
年月日はなくても大丈夫。
時は必須。
コンマ秒は任意。
timeライブラリのWebページ
Rubyリファレンスマニュアル
timeライブラリ > Timeクラス > parse
https://docs.ruby-lang.org/ja/latest/method/Time/s/parse.html
Timeオブジェクトを呼び出す
年月日時分秒コンマ秒を個別に呼び出す
書式は次のとおり。
Timeオブジェクト.year Timeオブジェクト.mon Timeオブジェクト.day Timeオブジェクト.hour Timeオブジェクト.min Timeオブジェクト.sec Timeオブジェクト.usec
書式を指定して表示する strftimeメソッド
strftimeメソッドの書式は次のとおり。
Timeオブジェクト.strftime("書式")
書式に使う主な記号は次のとおり。
%M: 分 %S: 秒 %L: ミリ秒 %nN: 小数点以下nケタ秒
フォーマットの詳細はWebページに載っている。
Rubyリファレンスマニュアル Timeクラス
インスタンスメソッド strftime
https://docs.ruby-lang.org/ja/latest/class/Time.html#I_STRFTIME
コードを書く
実際にコードを書く。
ボートレース(レガッタ)、2017年全日本選手権、男子エイトの優勝タイムと準優勝タイム、5分47秒コンマ74秒と5分51秒コンマ44秒をTimeオブジェクトにする。
time_test.rb
#組み込みクラスでゴールタイムをつくる goal_time = Time.local(2018,4,25,0,5,47,74) #タイムを読み込む puts "組み込みクラスでつくったタイム" p goal_time p goal_time.min p goal_time.sec p goal_time.usec puts "#{goal_time.strftime("%M:%S.%2N")}" #文字列をTimeオブジェクトに変換する require 'time' time_str = "05:51.44" goal_time_fromstr = Time.parse("00:" + time_str) #タイムを読み込む puts "文字列から変換したタイム" p goal_time_fromstr p goal_time_fromstr.min p goal_time_fromstr.sec p goal_time_fromstr.usec puts "#{goal_time_fromstr.strftime("%M:%S.%2N")}"
コードの説明
- 組み込みクラスでゴールタイムをつくる
- localメソッドを使う
- 引数には年,月,日,時,分,秒を数値で記入。コンマ秒は任意
- localメソッドを使う
- タイムを読み込む
- Timeオブジェクト全体をpメソッドで表示
- minメソッドで分を表示
- secメソッドで秒を表示
- usecメソッドでコンマ秒を表示
- strftimeメソッドで形式を指定して表示
- %2Nはコンマ秒を下2ケタで表示
- 文字列をTimeオブジェクトに変換する
- timeライブラリをrequireで読み込む
- タイムの文字列を変数に代入
- 文字列をTimeオブジェクトに変換
- parseメソッドを使う
- 引数の単位に「時間」は必須なので変数の頭に
00:
を加える
- 読み込みは組み込みクラスでつくったタイム出力と同じ
実行結果
組み込みクラスでつくったタイム 2018-04-25 00:05:47 +0900 5 47 74 05:47.00 文字列から変換したタイム 2018-04-25 00:05:51 +0900 5 51 440000 05:51.44
全体表示の+900
は標準時(イギリス グリニッジ天文台の時刻)に9時間足しました、という意味。
+900ならば日本時間をあらわしていることになる。
Time.local
とTime.parse
でusecメソッドの結果に(桁数の)違いがある。
Time.local
でつくったオブジェクトの場合、strftimeメソッドの%2Nは正しく表示されない。
Timeオブジェクトになっているか確認する
Timeオブジェクトかどうか時間差を求めて確認する。
time_test2.rb
require 'time' #組み込みクラスでゴールタイムをつくる goal_time = Time.local(2018,4,25,0,5,47,74) #文字列をTimeオブジェクトに変換する time_str = "05:51.44" goal_time_fromstr = Time.parse("00:" + time_str) #タイム差をもとめる time_lag = goal_time_fromstr - goal_time puts "2つのタイムの差は#{time_lag}秒です。" #classメソッドで確認する puts "goal_timeのクラスは: #{goal_time.class}" puts "goal_time_fromstrのクラスは: #{goal_time_fromstr.class}" puts "time_lagのクラスは: #{time_lag.class}" #タイムを比較する p goal_time < goal_time_fromstr p goal_time > goal_time_fromstr
実行結果
2つのタイムの差は4.439926秒です。 goal_timeのクラスは: Time goal_time_fromstrのクラスは: Time time_lagのクラスは: Float true false
実行結果からTimeオブジェクトになっているのがわかる。
-
で計算したタイム差はTimeクラスではなくFloatクラスになる。
肝心の引き算の答えがおかしい。
localメソッドでつくったオブジェクトは小数点以下秒数がうまく呼び出せない。
小数点以下の秒数をあつかう場合
Timeオブジェクトのつくりかたをそろえて計算してみる。
re_time_test2.rb
require 'time' localtime1 = Time.local(2018,4,25,0,5,47,74) localtime2 = Time.local(2018,4,25,0,5,51,44) parsetime1 = Time.parse("00:05:47.74") parsetime2 = Time.parse("00:05:51.44") puts "parse - local: #{parsetime2 - localtime1}" puts "localメソッド同士: #{localtime2 - localtime1}" puts "parseメソッド同士: #{parsetime2 - parsetime1}"
実行結果
parse - local: 4.439926 localメソッド同士: 3.99997 parseメソッド同士: 3.7
3つとも結果が違うので注意が必要。
小数点以下の秒数がある場合、parseメソッドを使って文字列から変換するやりかたがよさそう。
今回の動作確認環境
macOS 10.13.4
Ruby 2.4.4p296
ターミナル 2.8.2
Windows10 1709
Ruby 2.5.1p57 [x64-mingw32]
Windows PowerShell 5.1.16299.251