![]() |
るびくる: |
![]() |
RB(あーるびー): |
![]() |
こんにちは、ルビーライトカーバンクルのるびくるです! 今日もRuby Facetsの紹介いってみよー! |
![]() |
……まさかと思うけどその妙な肩書き、に対抗してる? |
![]() |
それじゃ今回は、facets/timeを紹介するよ。 |
# encoding: utf-8 require 'facets/time' time = Time.new(2013, 2, 5, 17, 42, 50) p time # => 2013-02-05 17:42:50 +0900 #------------------------------------------------------------------------------- # Time.elapse: ブロックの実行時間を計測する p Time.elapse{ sleep(1) } # => 1.0000581741333008 #------------------------------------------------------------------------------- # stamp: 対象の日時を指定したフォーマットで文字列化 # Time.stamp: 現在日時を指定したフォーマットで文字列化 p time.stamp(:db) # => "2013-02-05 17:42:50" p time.stamp(:utc) # => "2013-02-05 17:42:50" p time.stamp(:utcT) # => "2013-02-05T17:42:50" p time.stamp(:number) # => "20130205174250" p time.stamp(:time) # => "17:42" p time.stamp(:ruby18) # => "Tue Feb 05 17:42:50 +0900 2013" p Time.stamp(:db) # Time.now.stamp(:db)と同じ # stampに文字列を渡すと、strftimeとほぼ同じ動きになる # ただしstrftimeと違い、前後の空白は削除される p time.stamp('%Y/%m/%d') # => "2013/02/05" p time.stamp(' %Y/%m/%d ') # => "2013/02/05" # 引数に何も渡さなかった場合は、to_sと同じ動きになる p time.stamp # => "2013-02-05 17:42:50 +0900" p time.to_s # => "2013-02-05 17:42:50 +0900" #------------------------------------------------------------------------------- # shift, hence, in: 時間を指定した分だけ先に進める # 単位には以下のものが使用可能(単数形もOK) # :years, :months, :weeks, :days, :hours, # :minutes(:mins), :seconds(:secs) # # ago, less : 時間を指定した分だけ前に戻す(shift, hence, inの逆) p time # => 2013-02-05 17:42:50 +0900 p time.shift(5, :days, 1, :hour) # => 2013-02-10 18:42:50 +0900 p time.shift(-2, :weeks) # => 2013-01-22 17:42:50 +0900 p time.ago(2, :weeks) # => 2013-01-22 17:42:50 +0900 # 別記法: Hashで引数を渡すこともできる p time.shift(:days => 5, :hour => 1) # => 2013-02-10 18:42:50 +0900 p time.shift(days: 5, hour: 1) # => 2013-02-10 18:42:50 +0900 #------------------------------------------------------------------------------- # future? : self > otherと同じ。「指定した日付よりも未来であるかどうか」を判定する # past? : self < otherと同じ。「指定した日付よりも過去であるかどうか」を判定する p time # => 2013-02-05 17:42:50 +0900 p time + 30 # => 2013-02-05 17:43:20 +0900 p time.future?(time + 30) # => false p time.past?(time + 30) # => true #------------------------------------------------------------------------------- # trunc : 時刻を指定した単位(秒)で丸める(切り捨てる) # 60 なら1分単位、60 * 60 なら1時間単位 # round_to: 時刻を指定した単位(秒)でみて、近い方の時刻に寄せる(四捨五入のような処理を行う) p time # => 2013-02-05 17:42:50 +0900 p time.trunc(60) # => 2013-02-05 17:42:00 +0900 p time.trunc(60 * 60) # => 2013-02-05 17:00:00 +0900 p time.round_to(60) # => 2013-02-05 17:43:00 +0900 p time.round_to(60 * 60) # => 2013-02-05 18:00:00 +0900 # 注意点: 日単位でtruncやround_toを実行すると、期待したような結果にならない p time.trunc(60 * 60 * 24) # => 2013-02-05 09:00:00 +0900
![]() |
長っ! ざっと8種類くらいのメソッドがあるよ!? |
![]() |
それ、少なくとも2GBくらいの容量はあるってことだよね? それくらいあれば余裕だと思うけど……。 |
![]() |
まずはシンプルだけど地味に使う機会が多い、Time.elapseメソッドから。 |
#------------------------------------------------------------------------------- # Time.elapse: ブロックの実行時間を計測する p Time.elapse{ sleep(1) } # => 1.0000581741333008
![]() |
ブロックを渡すことで、そのブロック内の処理の実行時間を計測してくれるメソッドだよ。 |
![]() |
benchmarkライブラリの、Benchmark.realtimeと同じようなメソッドなんだね。 |
![]() |
英語で「(時間が)経過する」っていう意味の言葉だね。elapsed timeで経過時間って訳されたりするよ。 |
![]() |
次は、日時をいろいろなフォーマットで文字列化してくれるstampメソッド。 |
#------------------------------------------------------------------------------- # stamp: 対象の日時を指定したフォーマットで文字列化 # Time.stamp: 現在日時を指定したフォーマットで文字列化 p time.stamp(:db) # => "2013-02-05 17:42:50" p time.stamp(:utc) # => "2013-02-05 17:42:50" p time.stamp(:utcT) # => "2013-02-05T17:42:50" p time.stamp(:number) # => "20130205174250" p time.stamp(:time) # => "17:42" p time.stamp(:ruby18) # => "Tue Feb 05 17:42:50 +0900 2013" p Time.stamp(:db) # Time.now.stamp(:db)と同じ # stampに文字列を渡すと、strftimeとほぼ同じ動きになる # ただしstrftimeと違い、前後の空白は削除される p time.stamp('%Y/%m/%d') # => "2013/02/05" p time.stamp(' %Y/%m/%d ') # => "2013/02/05" # 引数に何も渡さなかった場合は、to_sと同じ動きになる p time.stamp # => "2013-02-05 17:42:50 +0900" p time.to_s # => "2013-02-05 17:42:50 +0900"
![]() |
えーと……これって、要するに決められたSymbolを渡すことで |
![]() |
その通り。time.stamp(:utc)って書くことで、timeをUTC(世界協定時)形式の文字列にしてくれる……というふうに |
# stampに文字列を渡すと、strftimeとほぼ同じ動きになる # ただしstrftimeと違い、前後の空白は削除される p time.stamp('%Y/%m/%d') # => "2013/02/05" p time.stamp(' %Y/%m/%d ') # => "2013/02/05" # 引数に何も渡さなかった場合は、to_sと同じ動きになる p time.stamp # => "2013-02-05 17:42:50 +0900" p time.to_s # => "2013-02-05 17:42:50 +0900"
![]() |
え、なんで? |
||||||||||||||||||||||||||||||||||||
![]() |
文字列を渡せばstrftimeメソッドの動き、引数なしで呼び出せばto_sメソッドの動き、ってところが |
||||||||||||||||||||||||||||||||||||
![]() |
そっか、普段なら目的に応じてstrftimeとto_sを使い分けたりする必要があるけれど |
||||||||||||||||||||||||||||||||||||
![]() |
それもきっと聞かれるだろうと思って、ちゃんと引数とフォーマットの対応表を用意してある。
|
||||||||||||||||||||||||||||||||||||
![]() |
さっすが先生! この表を見れば、いつでもstampの使い方はばっちりだね! |
||||||||||||||||||||||||||||||||||||
![]() |
ただ、指定可能なフォーマットの種類は、Facetsのバージョンによって増えたりしてるみたいだし |
![]() |
さて、ここからは数も多いし、サクサク進めていこう。 |
#------------------------------------------------------------------------------- # shift, hence, in: 時間を指定した分だけ先に進める # 単位には以下のものが使用可能(単数形もOK) # :years, :months, :weeks, :days, :hours, # :minutes(:mins), :seconds(:secs) # # ago, less : 時間を指定した分だけ前に戻す(shift, hence, inの逆) p time # => 2013-02-05 17:42:50 +0900 p time.shift(5, :days, 1, :hour) # => 2013-02-10 18:42:50 +0900 p time.shift(-2, :weeks) # => 2013-01-22 17:42:50 +0900 p time.ago(2, :weeks) # => 2013-01-22 17:42:50 +0900
![]() |
簡単に言うと、ある日時を「1日分未来に進めたい」ってときや「30分だけ過去に戻したい」って時なんかに |
![]() |
タイムスリップしたいときに使えるメソッドだってこと? |
![]() |
あー、うん。SFぽく言うならそういうことだね。 |
![]() |
で、使い方はだいたい見た目通りだね。 |
![]() |
たぶんそれは、英語としてそのまま読めるように、英語の語順に合わせた順番になってるからだね。 |
# 別記法: Hashで引数を渡すこともできる p time.shift(:days => 5, :hour => 1) # => 2013-02-10 18:42:50 +0900 p time.shift(days: 5, hour: 1) # => 2013-02-10 18:42:50 +0900
![]() |
なるほど、こっちの書き方なら、わたしみたいな生粋の日本生まれ・日本育ちにも違和感が少ないね! |
![]() |
いや、なんでもないよ。 |
![]() |
次は日時の比較を行う、future?と、past?。 |
#------------------------------------------------------------------------------- # future? : self > otherと同じ。「指定した日付よりも未来であるかどうか」を判定する # past? : self < otherと同じ。「指定した日付よりも過去であるかどうか」を判定する p time # => 2013-02-05 17:42:50 +0900 p time + 30 # => 2013-02-05 17:43:20 +0900 p time.future?(time + 30) # => false p time.past?(time + 30) # => true
![]() |
これは使い方も見たまんまだし、特に付け加えることはないね。 |
![]() |
これもどっちかって言うと、英語圏の人向けのメソッドなのかな? |
![]() |
最後は、日時の丸めを行うround_toと、trunc。 |
#------------------------------------------------------------------------------- # trunc : 時刻を指定した単位(秒)で丸める(切り捨てる) # 60 なら1分単位、60 * 60 なら1時間単位 # round_to: 時刻を指定した単位(秒)でみて、近い方の時刻に寄せる(四捨五入のような処理を行う) p time # => 2013-02-05 17:42:50 +0900 p time.trunc(60) # => 2013-02-05 17:42:00 +0900 p time.trunc(60 * 60) # => 2013-02-05 17:00:00 +0900 p time.round_to(60) # => 2013-02-05 17:43:00 +0900 p time.round_to(60 * 60) # => 2013-02-05 18:00:00 +0900 # 注意点: 日単位でtruncやround_toを実行すると、期待したような結果にならない p time.trunc(60 * 60 * 24) # => 2013-02-05 09:00:00 +0900
![]() |
日時の丸め……? ってどういうこと? |
![]() |
えーっと、たとえば数値(Numeric)にはroundやfloorってメソッドがあるよね? |
# 四捨五入 1.5.round # => 2 # 切り捨て 1.5.floor # => 1
![]() |
今回紹介するround_toやtruncも、考え方としてはそれに似てる。 |
![]() |
そっか、時間の四捨五入や切り捨てができる、ってことなんだね! |
![]() |
そういうこと。 |
# 注意点: 日単位でtruncやround_toを実行すると、期待したような結果にならない p time.trunc(60 * 60 * 24) # => 2013-02-05 09:00:00 +0900
![]() |
あれ!? この結果って「2013-02-05 09:00:00」(9時)になるの? |
![]() |
うん。ちょっと不思議な感じがするよね? |
![]() |
あー、そういうことかぁ……。 |
![]() |
そう。だから残念だけど、これらのメソッドでは |
![]() |
それじゃ、パート3のfacets/time編はここで終わり。 |
![]() |
えー、でもblank?メソッドやpresent?メソッドの使い方って |
![]() |
るびくるストップ! それ言い始めるとパート2のfacets/kernel/try解説も |
続きます。