In my controller, I would like to validate wether the time is before or
after 10:30 a given day. The only way I've found so far is convert back
from time to string to integer and so forth using the strftime-method,
which seems a bit overkill.
Somewhere along the lines of Time.now => 10:30, although I can't seem to
find the proper methods to accomplish this.
Is there such a simple way to do this seemlingly mundane task?
Another issue I'm struggling with regarding Time is that I can't seem to
find a way to search in my database based on time.
I have an arrival time:
@arrival_time = Time.parse("11:30")
and a flights-table with an arrival_time column, created with :time in
migrations. I can't seem to find a way to search for "arrival_time
earlier than @arrival_time". Obviously my second-workaround won't cut it
here.
Anyone had the same problem and/or have a possible a solution?
For your original problem, @time > @time.change(:hour => 10, :min =>
30) might be a bit more readable that what you've got. Also look into
using method like advance (or in rails 2.0 just time = time + 1.day)
as those are clever enough to get things right when days aren't 24
hours long ( when DST kicks in and so on)
Another issue I'm struggling with regarding Time is that I can't seem to
find a way to search in my database based on time.
I have an arrival time:
@arrival_time = Time.parse("11:30")
and a flights-table with an arrival_time column, created with :time in
migrations. I can't seem to find a way to search for "arrival_time
earlier than @arrival_time". Obviously my second-workaround won't cut it
here.
Does everything just work as expected here ?
Flights.find :all, :condition => ['arrival_time < ?',@arrival_time]
seems to work for me.
For your original problem, @time > @time.change(:hour => 10, :min =>
30) might be a bit more readable that what you've got. Also look into
using method like advance (or in rails 2.0 just time = time + 1.day)
as those are clever enough to get things right when days aren't 24
hours long ( when DST kicks in and so on)
The cleverness is not in 1.day, but in the #ago and #since methods. 1.day.since(@time) would give you a 23, 24, or 25 hour change depending on whether you cross a DST boundary in either direction.
For your original problem, @time > @time.change(:hour => 10, :min =>
30) might be a bit more readable that what you've got. Also look into
using method like advance (or in rails 2.0 just time = time + 1.day)
as those are clever enough to get things right when days aren't 24
hours long ( when DST kicks in and so on)
The cleverness is not in 1.day, but in the #ago and #since methods.
1.day.since(@time) would give you a 23, 24, or 25 hour change
depending on whether you cross a DST boundary in either direction.
Actually in 2.0, 1.day is clever and those do work (happily today is
the day where DST kicked in here so it's easy to test!).
1.day (and 1.month etc...) used to just return some fixed number of
seconds, but they are now instances of ActiveSupport::Duration, which
know how to handle all the various cases.
I'm actually having the same problem right now, since ruby doesn't
have a class that deals with time, without a date attached to it.
I've been playing around with rolling my own sudo Time class that just
handles hours, minutes, and seconds. Along those lines, I'm trying it
with storing the data as an integer in the database as seconds in the
day. So, for example, 1AM would be 3600.
Then I will use composed_of to instantiate that integer into my sudo
Time object. Playing around, it seems to work. I can define a to_s
method on the sudo Time class and it will print it out in time, then I
don't have to have all those strftime method calls in my views. By
having a to_i method, ar seems to convert that into an integer
correctly when saving.
The other alternative is to convert that Time object into something
that the database understands for searches and then again in the
views. But, it sounds like you were already doing that.
Maybe a monkeypatch on the Time class would help so you don't have to
remember the strftime all the time.
class Time
def to_time
self.strftime("%R")
end
end
time = Time.parse("10:30")
conditions = ["arrival_time < '#{time.to_time}'"] if time
Although, perhaps it would be better to just create a new class that
simply stores the Time object in it and then calls the strftime on
to_s, inspect, etc... Then use composed_of in your model.
Hope that helps a little bit, I would be interested to hear what you
decide to do. If I come up with anything I think is good, I'd be
happy to share it.
By
having a to_i method, ar seems to convert that into an integer
correctly when saving.
Actually, I don't think it is calling to_i, its calling what I map
that to in my composed_of block. First, time I've used composed_of,
its pretty neat.