How to judge whether a time/date is today, in ruby? - ruby-on-rails

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.

Related

Rails: What is the correct way of saving the time of a video?

There is a time span for every video. For example, for every youtube video, the time it last may be 4minutes or 30s.
The problem is how shold I save it into database?
Just store it as a string like 4:30? Or change it to seconds and store it as an integer? Then how can I change it back to minute:second format?
An additonal note:
Now I'm making a video congrugator, so the time actually come in as seconds: 30, or just in plain format like 4:30, then how can I turn the latter format into seconds integer?
The way of keeping time depends of you business logic.
I would prefer to keep length in seconds, and then convert to minutes, hours and so on.
You can easily do it by simple devision:
minutes = (seconds / 60)
seconds_left = (seconds % 40)
human_time = "#{minutes}:#{seconds_left}"
You can use the Time class to parse your time string.
require 'date' # Only needed outside of rails!
require 'active_support/all' # Only needed outside of rails!
video_length = "04:30"
# This ensures the format of video_length is HH:MM:SS
def hours_minutes_seconds(str)
parts = str.split(':').reverse
len = parts.length
if ! parts.length || parts.length > 3
raise("bad input (#{str}) for hours_minutes_seconds") and return
end
(0..2).map do |i|
part = parts[len -i]
part || "00"
end.join(':')
end
#Remember how unix time starts at 1 Jan 1970?
time = DateTime.iso8601( "1970-01-01T#{hours_minutes_seconds(video_length)}Z" )
# Lets print it out!
puts time.utc.strftime("%H:%M:%S") # 00:04:30
You could then store the value as the number of seconds [integer]. Getting a time object back from the length in seconds is easy.
puts Time.at(seconds).utc.strftime("%H:%M:%S") # 00:04:30

Finding "Next Tuesday" in Ruby

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.

Rails calculate time difference

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.

How can i check whether the current time in between tonight 9pm and 9am(tomorrow) in Ruby on Rails

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

Ruby: Math functions for Time Values

How do I add/subtract/etc. time values in Ruby? For example, how would I add the following times?
00:00:59 + 00:01:43 + 00:20:15 = ?
Use ActiveSupport, which has a ton of built-in date extensions.
require 'active_support/core_ext'
t1 = "#{Date.today} 00:00:59".to_time
t2 = "#{Date.today} 00:01:43".to_time
t3 = "#{Date.today} 00:20:15".to_time
t1.since(t2.seconds_since_midnight+t3.seconds_since_midnight)
or, if you don't care about the date, only time:
t1.since(t2.seconds_since_midnight+t3.seconds_since_midnight).strftime("%H:%M:%S")
For a full list, check out http://guides.rubyonrails.org/active_support_core_extensions.html#extensions-to-date
Kind of ugly, but you could use DateTime.parse(each_interval) & calculate the number of seconds in each. Like this:
require 'date'
def calc_seconds(time_string)
date_time = DateTime.parse(time_string)
hour_part = date_time.hour * 60 * 60
minute_part = date_time.minute * 60
second_part = date_time.second
hour_part + minute_part + second_part
end
...which gives you your result in seconds, assuming valid inputs. At which point you can add them together.
You could reverse the process to get the interval in your original notation.
I really think there ought to be an easier method, but I don't know of one.
One way would be to convert everything to seconds and then performing the operations... Then you would need to convert it again to a time object with
Time.at(seconds_result).strftime('%H:%M:%S')
And you would get the time nicely formatted (as a string).
I am trying to find a gem that does this, and other operations.
You probably want to use a gem that does not concern itself with the actual day. You could perform acrobatics using DateTime and or Time, but you would constantly be battling how to handle days.
One gem that may be useful is tod (TimeOfDay), https://github.com/JackC/tod
With that you could directly do TimeOfDay.parse "00:01:43", add the values, and print the result using strftime("%H:%M:%S").

Resources