Time Manipulation in Ruby

Time manipulation in ruby

A Time is a number of seconds since an epoch whereas a DateTime is a number of days since an epoch which is why adding 1 to a DateTime adds a whole day. You can however add fractions of a day, for example

d = DateTime.now
d + Rational(10, 86400)

Will add 10 seconds to d (since there are 86400 seconds in a day).

If you are using Rails, Active Support adds some helper methods and you can do

d + 20.minutes + 10.seconds

Which will do the right thing is d is a DateTime or a Time. You can use Active Support on its own, and these days you can pull in just the bits you need. I seem to recall that this stuff is in activesupport/duration. I believe there are a few other gems that offer help with time handling too.

Ruby - Manipulating Time/DateTime by the Hour/Day?

You chould check out active_support gem for this. It has nifty time/date manipulation methods so you can do stuff like this:

Time.now - 3.weeks - 2.days - 5.hours - 35.minutes

How to make time return morning or afternoon

You don't need any string manipulation:

t = Time.now
# => 2016-05-11 20:26:11 +0800
t.hour
# => 20

Just compare its hour (an integer) with 12.

Representing time differences in Ruby

Not in the stdlib, but there is a Gem that you can use for the job - the duration gem.

sudo gem install duration

Which you can use like this:

require "duration"
a = Time.now
sleep(5)
b = Time.now
duration = Duration.new(b - a)
# => #<Duration: 5 seconds>
duration.seconds
# => 5
duration.minutes
# => 0

And days, hours, weeks and a bunch of other useful methods.

You can also then monkey-patch Time, Date and other date-time classes to return Duration objects.

Deep diving into timing manipulation of Chef resources

You have some misunderstanding about how it works.

  1. During the compile phase, recipes are evaluated, the ruby code is them is run and a resource collection is build in the order the resources appear.
  2. At converge time, chef iterate on the resource collection, calling the action code for this resource.
  3. If a resource is updated and there's a notify or subscribe, then there's 2 options (I'll talk only about notify, subscire is just the pendant to the target)

    • :immediately -> the action method given in notify for target is called immediately
    • :delayed -> The action is queued up to be executed at end of run.

Note that for the 3. The resource collection is never changed during converge pgase, there's a separate queue created to run the :delayed notifications at end of run.


In other words, if recipe foo calls resource bar which includes
resource oof how can we place resource oof onto the resource
collection of recipe foo.

If I correctly understand what you mean, you wish the inner resource from a LWRP to show up in the run resource collection.

What happens with a LWRP is that the LWRP resource is added to the resource collection of the run at compile time. Once in converge time and at the call of this LWRP, an 'inner' chef is launched which will evaluated the provider code as a recipe, this inner run has no idea of what is in parent resource collection, so you can't notify an external resource within it.

This behavior is controled by use_inline_resource parameter.

Since chef 12.5 the new custom_resource model change the way LWRP are done and aim at simplifying theyr writing, the old syntax is announced to be deprecated.

Disabling the use_inline_resource in your LWRP sounds then a bad idea, what do you really try to achieve ? I've the feeling you're asking for a XY problem which maybe can be solved differently than your actual thinking.

How to use Rails' DateTime class to add minutes and seconds

You are not assigning the form data to an instance variable.

In your new method you need to do that explicitly

def create
@start_time = params[:start_time]
...
end

Date manipulation Rails 4.1

The best solution here would be to write your own helper. I'm not going to do the whole thing for you, but this should get you started.

Add this to your application_helper.rb:

module ApplicationHelper
def format_date(date)
tomorrow = Time.current.beginning_of_day + 1
day_after_tomorrow = tomorrow + 1
end_of_week = Time.current.end_of_week

if date >= tomorrow && date < day_after_tomorrow
'Tomorrow'
elsif date >= day_after_tomorrow && date <= end_of_week
'This week'
else
'Some other date'
end
end
end

This isn't necessarily the most efficient way of writing this, but I wanted to keep things relatively simple.

Then in your view, just use the helper to format your date:

<%= format_date(@event.date) %>

EDIT

Updated to use Time.current. Thanks to @house9 for the tip.

Converting Time strings into proper Formats in Ruby

Assuming input strings will always be in same format:

time = string_a.scan(/\d+/)
time[0] + ":" + time[1].rjust(2,'0')
# => "1:06"

string_b = "3 minutes, 35 seconds"
timeb = string_b.scan(/\d+/)
timeb[0] + ":" + timeb[1].rjust(2,'0')
# => "3:35"

You can make your regex stricter, however if the input strings are always in "m minute, s seconds" format then this should be sufficient.



Related Topics



Leave a reply



Submit