Rubyフォームから入力されるDateTime。さらに、フォームからn時間もあります。前のDateTimeからこれらのn時間を減算します。時間範囲)。
DateTimeには、日と月を減算する2つのメソッド「-」と「<<」がありますが、時間はありません。 ( [〜#〜] api [〜#〜] )。私はそれをどのように行うことができますか?
これを行うことができます。
adjusted_datetime = (datetime_from_form.to_time - n.hours).to_datetime
1日未満を差し引くことができます。
two_hours_ago = DateTime.now - (2/24.0)
これは数分でも機能します:
hours = 10
minutes = 5
seconds = 64
hours = DateTime.now - (hours/24.0) #<DateTime: 2015-03-11T07:27:17+02:00 ((2457093j,19637s,608393383n),+7200s,2299161j)>
minutes = DateTime.now - (minutes/1440.0) #<DateTime: 2015-03-11T17:22:17+02:00 ((2457093j,55337s,614303598n),+7200s,2299161j)>
seconds = DateTime.now - (seconds/86400.0) #<DateTime: 2015-03-11T17:26:14+02:00 ((2457093j,55574s,785701811n),+7200s,2299161j)>
浮動小数点演算の不正確さが問題になる場合は、Rational
またはその他の安全な演算ユーティリティを使用できます。
このような振る舞いをより明確にしたい場合は、事前の方法がいいです。
adjusted = time_from_form.advance(:hours => -n)
1日のほんの一部を離陸する必要があります。
two_hours_ago = DateTime.now - (2.0/24)
n/24.0
トリックは、フロートが最終的に丸められるため、適切に機能しません。
>> DateTime.parse('2009-06-04 02:00:00').step(DateTime.parse('2009-06-04 05:00:00'),1.0/24){|d| puts d}
2009-06-04T02:00:00+00:00
2009-06-04T03:00:00+00:00
2009-06-04T03:59:59+00:00
2009-06-04T04:59:59+00:00
ただし、代わりにRationalクラスを使用できます。
>> DateTime.parse('2009-06-04 02:00:00').step(DateTime.parse('2009-06-04 05:00:00'),Rational(1,24)){|d| puts d}
2009-06-04T02:00:00+00:00
2009-06-04T03:00:00+00:00
2009-06-04T04:00:00+00:00
2009-06-04T05:00:00+00:00
Railsで作業している場合、次の超直感的な可能性があります。
> Time.now - 12.hours
=> 2019-08-19 05:50:43 +0200
(これはseconds、minutes、days、およびyearsでも機能します)
rubyのみを使用している場合、DateTime
はこれを行えませんが、Time
は次のことができます。
t = Time.now
t = t - (hours*60**2)
Time
は日付情報も格納することに注意してください。これは少し奇妙です。
DateTime
を使用する必要がある場合
DateTime.commercial(date.year,date.month,date.day,date.hour-x,date.minute,date.second)
動作するかもしれませんが、butいです。ドキュメントには、DateTime
は不変であると書かれているので、-
および<<
[〜#〜] edit [〜#〜]:アプローチを使用する前に この質問 を見てくださいここで概要を説明しました。 Ruby(これは理解できます)で基本クラスの動作を変更することはベストプラクティスではないようです。だから、この答えを一粒で取ってください...
MattWの答え は私が最初に考えたものでしたが、私もあまり好きではありませんでした。
DateTime
とFixnum
にパッチを適用することで、見苦しくないものにできると思います。
require 'date'
# A placeholder class for holding a set number of hours.
# Used so we can know when to change the behavior
# of DateTime#-() by recognizing when hours are explicitly passed in.
class Hours
attr_reader :value
def initialize(value)
@value = value
end
end
# Patch the #-() method to handle subtracting hours
# in addition to what it normally does
class DateTime
alias old_subtract -
def -(x)
case x
when Hours; return DateTime.new(year, month, day, hour-x.value, min, sec)
else; return self.old_subtract(x)
end
end
end
# Add an #hours attribute to Fixnum that returns an Hours object.
# This is for syntactic sugar, allowing you to write "someDate - 4.hours" for example
class Fixnum
def hours
Hours.new(self)
end
end
その後、次のようにコードを記述できます。
some_date = some_date - n.hours
ここで、n
は、some_date
から減算する時間数です。
取得した値をどのように使用する必要があるかは言いませんでしたが、時間を24で割って1日の端数を差し引くのはどうですか?
mydatetime = DateTime.parse(formvalue)
nhoursbefore = mydatetime - n / 24.0
Time
の代わりにDateTime
を使用できる場合( 相互に変換するいくつかの方法 ):
# Just remove the number of seconds from the Time object
Time.now - (6 * 60 * 60) # 6 hours ago
Active_supportでヘルパーを使用するのが好きです。それは本当にきれいで読みやすくなります。
以下の例を参照してください。
require 'active_support'
last_accessed = 2.hours.ago
last_accessed = 2.weeks.ago
last_accessed = 1.days.ago
現在の日付が使用されている場合、そのような構文を使用して、探していることを実行する方法があるかもしれません。