سؤال

لدي روبي التاريخ والوقت الذي يحصل شغل من شكل.بالإضافة إلى ذلك يجب n ساعات من شكل كذلك.أود طرح تلك n ساعات من السابق DateTime.(للحصول على نطاق الوقت).

التاريخ والوقت اثنين من الأساليب "-" و "<<"إلى طرح اليوم و الشهر ، ولكن ليس ساعة.(API).أي اقتراحات كيف يمكنني فعل ذلك ؟

هل كانت مفيدة؟

المحلول

هل يمكن أن تفعل هذا.

adjusted_datetime = (datetime_from_form.to_time - n.hours).to_datetime

نصائح أخرى

ويمكنك فقط طرح أقل من يوم واحد كله:

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)

تحتاج فقط إلى اتخاذ قبالة أجزاء من اليوم.

two_hours_ago = DateTime.now - (2.0/24)
  • 1.0 = يوم واحد
  • 1.0/24 = 1 ساعة
  • 1.0/(24*60) = 1 دقيقة
  • 1.0/(24*60*60) = 1 الثاني

وسوف 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

ويمكنك، ومع ذلك، استخدام الطبقة الرشيد بدلا من ذلك:

>> 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

وأنت لم تقل ما تستخدم ما تحتاجه لجعل قيمة تحصل عليه، ولكن ماذا عن مجرد تقسيم ساعات عن طريق 24 لذلك كنت بطرح جزء من اليوم؟

mydatetime = DateTime.parse(formvalue)
nhoursbefore = mydatetime - n / 24.0

تعديل : لنلقي نظرة على الموقع هذا السؤال قبل أن تقرر استخدام نهج لقد المذكورة هنا. ويبدو أنه قد لا يكون أفضل الممارسات لتعديل سلوك الفئة الأساسية في روبي (التي أستطيع أن أفهم). لذا، تأخذ هذه الإجابة مع حبة الملح ...


كان

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 هو عدد الساعات التي تريد substract من some_date

وDateTime لا تستطيع أن تفعل هذا، ولكن Time القيام بما يلي:

t = Time.now
t = t-hours*60

لاحظ أن Time أيضا بتخزين معلومات التاريخ، كل شيء غريبا بعض الشيء.

إذا كان لديك للعمل مع DateTime

DateTime.commercial(date.year,date.month,date.day,date.hour-x,date.minute,date.second)

ويمكن أن تعمل، ولكن هو قبيح. يقول ثيقة DateTime هو غير قابل للتغيير، لذلك أنا لست حتى متأكدا من - و<<

إذا يسمح لي لاستخدام Time بدلا من DateTime (هناك <لأ href = "https://stackoverflow.com/questions/279769/convert-to-from-datetime-and-time-in-ruby/ 280026 # 280026 "> عدة طرق لترجمة واحدة ل آخر):

# 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

وربما تكون هناك وسيلة لاستخدام هذا النوع من جملة لتفعل ما كنت تبحث عنه، إذا تم استخدام التاريخ الحالي.

ويمكنك استخدام هذا:

Time.now.ago(n*60*60)

وعلى سبيل المثال Time.now.ago(7200) سيعطي التاريخ والوقت الذي كان قبل 2 ساعة من الآن.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top