Introduction
There are quite a few solutions here, and I began to think about their effectiveness (efficiency is probably not the most important aspect of this problem). I took a little from here and threw a couple of mine. (NB, although the OP asked to round to the next 15 minutes, I made my comparisons and samples in just 1 minute / 60 seconds for simpler samples).
Customization
Benchmark.bmbm do |x| x.report("to_f, /, floor, * and Time.at") { 1_000_000.times { Time.at((Time.now.to_f / 60).floor * 60) } } x.report("to_i, /, * and Time.at") { 1_000_000.times { Time.at((Time.now.to_i / 60) * 60) } } x.report("to_i, %, - and Time.at") { 1_000_000.times { t = Time.now.to_i; Time.at(t - (t % 60)) } } x.report("to_i, %, seconds and -") { 1_000_000.times { t = Time.now; t - (t.to_i % 60).seconds } } x.report("to_i, % and -") { 1_000_000.times { t = Time.now; t - (t.to_i % 60) } } end
results
Rehearsal ----------------------------------------------------------------- to_f, /, floor, * and Time.at 4.380000 0.010000 4.390000 ( 4.393235) to_i, /, * and Time.at 3.270000 0.010000 3.280000 ( 3.277615) to_i, %, - and Time.at 3.220000 0.020000 3.240000 ( 3.233176) to_i, %, seconds and - 10.860000 0.020000 10.880000 ( 10.893103) to_i, % and - 4.450000 0.010000 4.460000 ( 4.460001) ------------------------------------------------------- total: 26.250000sec user system total real to_f, /, floor, * and Time.at 4.400000 0.020000 4.420000 ( 4.419075) to_i, /, * and Time.at 3.220000 0.000000 3.220000 ( 3.226546) to_i, %, - and Time.at 3.270000 0.020000 3.290000 ( 3.275769) to_i, %, seconds and - 10.910000 0.010000 10.920000 ( 10.924287) to_i, % and - 4.500000 0.010000 4.510000 ( 4.513809)
Results Analysis
What to do with it? It’s good that your equipment can work faster or slower, so do not take the word for computers for it. As you can see, another thing is that if we do not perform these operations on a scale of millions of operations, it will not matter which method you use with respect to processing power (although note that, for example, most solutions for cloud computing provides very little computing power, and therefore millions can be hundreds or tens of thousands in such environments).
The slowest, but probably the most readable solution
In this sense, using it is clear that the slowest of them is t = Time.now; t - (t.to_i % 60).seconds t = Time.now; t - (t.to_i % 60).seconds can only be justified because .seconds is so cool there.
Not so slow and almost like a readable solution
However, since it is actually not needed at all and makes the operation twice as expensive as without it, I must say that my choice is t = Time.now; t - (t.to_i % 60) t = Time.now; t - (t.to_i % 60) . In my opinion, this is fast enough and a million times more readable than any other solutions presented here. That's why I think this is the best solution for your casual flooring, although it is significantly slower than the other three.
Awkward and not particularly slow or fast
The most voted solution on this page is Time.at((Time.now.to_f / 60).floor * 60) - this is the slowest of all the solutions on this page (before this answer) and much slower than the top 2 solutions. Using floats just to fit decimals also seems very illogical. For the rounded part, which would be fine, but rounding sounds like a “gender” to me. If something like it can be rounded or “ceiling”, that would be like t = Time.now; t - (60 - t.to_i % 60) % 60 t = Time.now; t - (60 - t.to_i % 60) % 60 or Time.at((Time.now.to_f / 60).ceil * 60) . The dual module that the to_i solution needs is a bit unpleasant, so although it is significantly faster, I would prefer the ceil method here. (Benchmarks are attached at the very end of this post)
For those who need speed
Associated (the differences are so insignificant that you cannot really announce the winner) are the top two performers in the test, where there are two to_i options that use a slightly different combination of operations and then convert the integer back to a Time object. If you are in a hurry, these are the ones you should use:
Time.at((Time.now.to_i / 60) * 60) t = Time.now.to_i; Time.at(t - (t % 60))
Setting for rounding / level comparison
Benchmark.bmbm do |x| x.report("to_f, /, ceil, * and Time.at") { 1_000_000.times { Time.at((Time.now.to_f / 60).ceil * 60) } } x.report("to_i, %, -, %, + and Time.at") { 1_000_000.times { t = Time.now; t + (60 - t.to_i % 60) % 60 } } end
Results for rounding / level comparison tests
Rehearsal ---------------------------------------------------------------- to_f, /, ceil, * and Time.at 4.410000 0.040000 4.450000 ( 4.446320) to_i, %, -, %, + and Time.at 3.910000 0.020000 3.930000 ( 3.939048) ------------------------------------------------------- total: 8.380000sec user system total real to_f, /, ceil, * and Time.at 4.420000 0.030000 4.450000 ( 4.454173) to_i, %, -, %, + and Time.at 3.860000 0.010000 3.870000 ( 3.884866)