2011-01-07 21 views
3

だから、私は時間の文字列を持っている...私はすべて秒にそれらを変換したいRuby(Rails)は時間の文字列を秒に変換しますか?

'4 hours' 
'48 hours' 
'3 days' 
'15 minutes' 

の線に沿って何かを。 '4 hours'の場合、これは

Time.parse('4 hours').to_i - Time.parse('0 hours').to_i 
=> 14400 # 4 hours in seconds, yay 

しかし正常に動作し、これは(レンジ誤差の外に)48時間動作しません。また、3日間(情報のエラーなし)などは動作しません。

これらの文字列を秒単位で簡単に変換できますか?


答えて

6

です。それはあなたが望むものではありません。私が考えることができるライブラリはすべて、この側面では似ています。時間の長さではなく、絶対時間に興味があります。

文字列を時間形式に変換するには、Chronic(gem install chronic)を使用することをお勧めします。秒に変換するには、現在の時刻を基準にすべてを行い、その時刻を減算して絶対秒数を求めます。

def seconds_in(time) 
    now = Time.now 
    Chronic.parse("#{time} from now", :now => now) - now 
end 

seconds_in '48 hours' # => 172,800.0 
seconds_in '15 minutes' # => 900.0 
seconds_in 'a lifetime' # NoMethodError, not 42 ;) 

夫婦簡単なメモ:慢性が必要な理由

  • from nowさがある - それは、自然言語入力を処理します。
  • 私たちは、Chronicが魔法を使う時からTime.nowが変化したときから安全になるように指定しています。それは今までには起こり得ないかもしれないが、残念なことにここより安全だと思う。
+0

私もこのために慢性で行くと思います。 –

+1

慢性期は機能しますが、慢性期は慢性的な慢性期がより容易になります。 https://github.com/hpoydar/chronic_durationにアクセスしてください。日付/時刻の解析についての素晴らしいブログ記事 - http://everydayrails.com/2010/08/11/ruby-date-time-parsing-chronic.html – Gokul

+0

@Gokul Looks役立ちます。 APIは一種の華やかです。 – coreyward

3
4.hours => 14400 seconds 
4.hours.to_i 14400 
4.hours - 0.hours => 14400 seconds 

def string_to_seconds string 
    string.split(' ')[0].to_i.send(string.split(' ')[1]).to_i 
end 

時間は、数のフォーマットである場合、このヘルパーメソッドのみ機能する[スペース]時間(S)/分(S)/秒(S)

+0

あなたはFixnumを使い始めていますが、彼はユーザーからの文字列の入力から始めると思います。 – coreyward

+0

ええ、まったく正直で、私はそれに気付き、以前はスキミングしていました。それを言いましたが、時間列が常に記述された一貫した形式であれば、文字列を解析して日時ヘルパーを使うのはなぜですか? – mark

3
'48 hours'.match(/^(\d+) (minutes|hours|days)$/) ? $1.to_i.send($2) : 'Unknown' 
=> 172800 seconds 
+0

これは 'a day'、 'one day'、 '1 week'、 '1 month'、 '48 Hours'などで失敗します。これは 'def solve_complex_problem;返答 '答え';終わり。 – coreyward

+0

はい、質問の例を渡します。私は2番目の文を理解していません。 – Heikki

+1

これまでに、特定の方法で応答したアプリケーションを作成する必要があると書かれたプログラミングコースを受講したことがありますか?ポイントは、例に文字通り応答するように記述するのではなく、実行するべき*機能*を推測し、そのように書くことです。 – coreyward

-1
>> strings = ['4 hours', '48 hours', '3 days', '15 minutes', '2 months', '5 years', '2 decades'] 
=> ["4 hours", "48 hours", "3 days", "15 minutes", "2 months", "5 years", "2 decades"] 
>> ints = strings.collect{|s| eval "#{s.gsub(/\s+/,".")}.to_i" rescue "Error"} 
=> [14400, 172800, 259200, 900, 5184000, 157788000, "Error"] 
+0

これは扱いにくいですが、ユーザ入力で 'eval'を使うのは非常に危険です。正規表現を使用して、入力が期待どおりのものであることを検証した場合(たとえば '/ \ d + \ s +(?: minutes | hours | days | ...)/')、これは悪くないでしょう。おそらくそれを解析し、 '.to_i.send(duration_string)'を使うほうが良いでしょう。 – Phrogz

+0

私はあなたが言っていることを見ます、それは注射の攻撃に脆弱です、それは事前に正規表現を確認する方が良いでしょう。 –

関連する問題