I have tried such code, but it doesn't work:
require 'time_diff'
cur_time = Time.now.strftime('%Y-%m-%d %H:%M')
time_diff_components = Time.diff(#art.datetime_of_update, Time.parse(cur_time))
if #art.PRICEM.to_f >= eprice.to_f || #art.PRICEM.blank? && time_diff_components[:hour] < 3 &&
but timediff is 0, in db time looks like this:
2012-08-28 19:53:12
How calculate difference in hour's between now and db?
Firstly, you should look at these two lines:
cur_time = Time.now.strftime('%Y-%m-%d %H:%M')
time_diff_components = Time.diff(#art.datetime_of_update, Time.parse(cur_time))
Why would you format the time and then only use the value as the input to a parsing operation? Surely it would be simpler - and less fragile - to write:
time_diff_components = Time.diff(#art.datetime_of_update, Time.now)
I don't know why Time.diff isn't working for you (I'm not a Ruby dev), but if the aim is to check whether the article was updated "less than 3 hours ago" then there's a simpler approach: subtract three hours from the current time, and compare the article's update time with that limit:
limit_time = Time.now + 3.hours
if #art.PRICEM.to_f >= eprice.to_f || #art.PRICEM.blank? && #art.datetime_of_update >= limit_time
If you don't have to be precise, you can use Rails' time_ago_in_words helper.
time_ago_in_words(Time.now - 3.hours)
#=> about 3 hours
of course, depending on the time difference, this can return 'minutes', 'days', etc. as well.
Related
I would like to get the following result based on created_at:
1-59M
1-24H
1-999+W
E.g, if a post is 5 minutes old it will say 5M. If it is 15 hours old it will say: 15H and lastly it will say 52W if it is 52 weeks old.
Bonus: how would I make it work with: https://github.com/basecamp/local_time
You just want it in weeks, hours or minutes? How about this (it would go in a helpers file)
def short_age_string(time)
diff = Time.now - time #value is seconds (float)
if diff >= 0
result = "1-"
else
result = "1+"
end
diff = diff.abs.to_i
if diff >= 604800 #seconds in a week
weeks = diff/604800
return "#{result}#{weeks}#{"+" if weeks >= 999}W"
elsif diff > 3600 #seconds in an hour
return "#{result}#{diff/3600}H"
else
return "#{diff/60}#{minutes}M"
end
end
I took the liberty of making it return "1+..." for times in the future.
I believe you'd use strftime to manage it with i18n
According to strftimer, you'd need to use %-dH, %-dM, %-dD, %-dW to get the format you desire:
#view
<%=l record.created_at, format: :small %>
#config/locales/en.yml
time:
small: %-dH
I've tried testing this & it will only bring back the initial number. More testing is needed, but should set you on the right track
require 'active_support/all'
days = 0.day.ago
days += 1 until days.since.wday == 2
next_tuesday = days.since
Above code is not doing right. But below is right. Could you tell me why?
require 'active_support/all'
current_day = 0.day.ago
current_day += 1.day until current_day.wday == 2
next_tuesday = current_day
First, mind that you're using ActiveSupport, so this is not pure Ruby. Assuming that, there is an easier way of doing so bundled in ActiveSupport:
Time.now.next_week(:tuesday)
It's possible doing date math using seconds as the interval, but that's old school and I'm sure you don't want to have us old people scare you with stories.
I'm away from my computer so this is untested, but here is the gist of what you want to do:
today = Date.today
today -= today.wday # normalize the day to the first day of the week, AKA Sunday
today += 9 # add a week + 2 days.
It can be stated on one line like:
Date.today - Date.today.wkday + 9
Or something in between the two.
I'm trying to generate random data in my rails application.
But I am having a problem with decimal amount. I get an error
saying bad value for range.
while $start < $max
$donation = Donation.new(member: Member.all.sample, amount: [BigDecimal('5.00')...BigDecimal('200.00')].sample,
date_give: Random.date_between(:today...Date.civil(2010,9,11)).to_date,
donation_reason: ['tithes','offering','undisclosed','building-fund'].sample )
$donation.save
$start +=1
end
If you want a random decimal between two numbers, sample isn't the way to go. Instead, do something like this:
random_value = (200.0 - 5.0) * rand() + 5
Two other suggestions:
1. if you've implemented this, great, but it doesn't look standard Random.date_between(:today...Date.civil(2010,9,11)).to_date
2. $variable means a global variable in Ruby, so you probably don't want that.
UPDATE --- way to really get random date
require 'date'
def random_date_between(first, second)
number_of_days = (first - second).abs
[first, second].min + rand(number_of_days)
end
random_date_between(Date.today, Date.civil(2010,9,11))
=> #<Date: 2012-05-15 ((2456063j,0s,0n),+0s,2299161j)>
random_date_between(Date.today, Date.civil(2010,9,11))
=> #<Date: 2011-04-13 ((2455665j,0s,0n),+0s,2299161j)>
I need to check whether my current times is between the specified time interval (tonight 9pm and 9am tomorrow). How can this be done in Ruby on Rails.
Thanks in advance
Obviously this is an old question, already marked with a correct answer, however, I wanted to post an answer that might help people finding the same question via search.
The problem with the answer marked correct is that your current time may be past midnight, and at that point in time, the proposed solution will fail.
Here's an alternative which takes this situation into account.
now = Time.now
if (0..8).cover? now.hour
# Note: you could test for 9:00:00.000
# but we're testing for BEFORE 9am.
# ie. 8:59:59.999
a = now - 1.day
else
a = now
end
start = Time.new a.year, a.month, a.day, 21, 0, 0
b = a + 1.day
stop = Time.new b.year, b.month, b.day, 9, 0, 0
puts (start..stop).cover? now
Again, use include? instead of cover? for ruby 1.8.x
Of course you should upgrade to Ruby 2.0
Create a Range object having the two Time instances that define the range you want, then use the #cover? method (if you are on ruby 1.9.x):
now = Time.now
start = Time.gm(2011,1,1)
stop = Time.gm(2011,12,31)
p Range.new(start,stop).cover? now # => true
Note that here I used the explicit method constructor just to make clear that we are using a Range instance. You could safely use the Kernel constructor (start..stop) instead.
If you are still on Ruby 1.8, use the method Range#include? instead of Range#cover?:
p (start..stop).include? now
require 'date'
today = Date.today
tomorrow = today + 1
nine_pm = Time.local(today.year, today.month, today.day, 21, 0, 0)
nine_am = Time.local(tomorrow.year, tomorrow.month, tomorrow.day, 9, 0, 0)
(nine_pm..nine_am).include? Time.now #=> false
This might read better in several situations and the logic is simpler if you have 18.75 for "18:45"
def afterhours?(time = Time.now)
midnight = time.beginning_of_day
starts = midnight + start_hours.hours + start_minutes.minutes
ends = midnight + end_hours.hours + end_minutes.minutes
ends += 24.hours if ends < starts
(starts...ends).cover?(time)
end
I'm using 3 dots because I don't consider 9:00:00.000am after hours.
Then it's a different topic, but it's worth highlighting that cover? comes from Comparable (like time < now), while include? comes from Enumerable (like array inclusion), so I prefer to use cover? when possible.
Here is how I check if an event is tomorrow in Rails 3.x
(event > Time.now.tomorrow.beginning_of_day) && (event < Time.now.tomorrow.end_of_day)
if time is between one day:
(start_hour..end_hour).include? Time.zone.now.hour
I have a settlement, I want to judge if the return_service_date is today, how to do this?
This is my code (rails):
if settlement.return_service_date &&
settlement.return_service_date.to_s(:date) == Time.now.to_s(:date)
Is there a better way to do this?
In Rails, you can do:
settlement.return_service_date.today?
For everyone who isn't using rails, my plain ruby solution with Time looks like the following, if you have Dates instead of Times you can convert them with .to_time()
# current time
time = Time.new()
# some time
some_time = Time.new() + 7550
# set beginning of today
today_start = Time.new(time.year,time.month,time.day)
# set ending of today
today_end = today_start + 86399
# check if some_time is in between today start and end
puts (today_start..today_end).cover?(some_time)
Depending on your current time it prints true (if your day still has at least 7550 seconds left) or false.