Argument error : invalid date - ruby-on-rails

What this error could be about? I'm defining an age at my account model:
def age
birthday = DateTime.new(year_Of_Birth.to_i, month_Of_Birth.to_i, day_Of_Birth.to_i)
self.age = ((DateTime.now - birthday) / 365.25).to_i
end
and in my view i get the following error:
ArgumentError - invalid date in the following line:
<dd><%= #account.age %></dd>
Thanks in advance.

Try to test in your Rails app console:
birthday = DateTime.new(1991,4,2) => Tue, 02 Apr 1991 00:00:00 +0000
DateTime.now - birthday => (149073456141953/17280000000)
(DateTime.now - birthday)/365.25 => 23.61926437561592
((DateTime.now - birtday)/365.25).to_i => 23
This works for me. Check the params that you're setting.

I'm almost sure the arguments that you're passing (year_Of_Birth.to_i, month_Of_Birth.to_i, day_Of_Birth.to_i) have something wrong, debug them and show us the values, or if you want you can try this to catch some specific error:
begin
birthday = DateTime.new(year_Of_Birth.to_i, month_Of_Birth.to_i, day_Of_Birth.to_i)
self.age = ((DateTime.now - birthday) / 365.25).to_i
rescue ArgumentError
#your logic
end

Related

Given a start and end date, how can I loop until I reach the end date?

I have a start_dt and an end_dt object that are of type datetime.
How can I loop from the start_dt, incrementing by 1 day each time until I reach the end date?
You can use the upto and downto methods on Date and DateTime objects:
start_dt = DateTime.parse('2018-01-01')
end_dt = DateTime.parse('2018-01-15')
start_dt.upto(end_dt) { |date| puts date }
2018-01-01T00:00:00+00:00
2018-01-02T00:00:00+00:00
2018-01-03T00:00:00+00:00
2018-01-04T00:00:00+00:00
2018-01-05T00:00:00+00:00
2018-01-06T00:00:00+00:00
2018-01-07T00:00:00+00:00
2018-01-08T00:00:00+00:00
2018-01-09T00:00:00+00:00
2018-01-10T00:00:00+00:00
2018-01-11T00:00:00+00:00
2018-01-12T00:00:00+00:00
2018-01-13T00:00:00+00:00
2018-01-14T00:00:00+00:00
2018-01-15T00:00:00+00:00
end_dt.downto(start_dt) { |date| puts date }
2018-01-15T00:00:00+00:00
2018-01-14T00:00:00+00:00
2018-01-13T00:00:00+00:00
2018-01-12T00:00:00+00:00
2018-01-11T00:00:00+00:00
2018-01-10T00:00:00+00:00
2018-01-09T00:00:00+00:00
2018-01-08T00:00:00+00:00
2018-01-07T00:00:00+00:00
2018-01-06T00:00:00+00:00
2018-01-05T00:00:00+00:00
2018-01-04T00:00:00+00:00
2018-01-03T00:00:00+00:00
2018-01-02T00:00:00+00:00
2018-01-01T00:00:00+00:00
How about this?
current_date = object.start_dt
end_date = object.end_dt
loop do
## do something
## (`:beginning_of_day` and `:end_of_day` may help you)
current_date += 1.day
break if current_date > end_date
end
Try to the following
start_date = Time.now - 30.day
=> 2017-12-16 09:19:51 +gmt
end_date = Time.now
=> 2018-01-15 09:19:44 +gmt
start_date = Date.parse "#{start_date}"
end_date = Date.parse "#{end_date}"
date_count = (end_date - start_date).to_i
=> 30
<% (1..date_count).each do |i| %>
#Code to display using <%= i %> that you want to display
<% end %>
Hope to help
Try these:
(DateTime.parse('2018-01-01')..DateTime.parse('2018-01-15')).each do |date|
puts date
end

Ruby difference between two dates

I need to check the difference between two date and check if there is 24 hours or more. I am having trouble in calling the to_time method of the date object. This to_time method is turning the minutes and seconds if the current date to 00:00:00.
Example:
date = Date.rfc3339('2017-08-16T17:55:49.000-03:00')
=> #<Date: 2017-08-16 ((2457982j,0s,0n),+0s,2299161j)>
date.to_time
2017-08-16 00:00:00 -0300
(( Date.today.to_time - date.to_time)/3600).round
=> 24
Date does not include Time. Use DateTime instead.
require 'date'
dt = DateTime.rfc3339('2017-08-16T17:55:49.000-03:00')
puts (Time.now - dt.to_time)/(60*60) > 24
You can do:
datetime_1 = DateTime.parse("2017-08-17T13:36:03-04:00")
datetime_2 = DateTime.parse("2017-08-16T13:33:03-04:00")
greatest_datetime = [datetime_1, datetime_2].max
smallest_datetime = [datetime_1, datetime_2].min
(greatest_datetime - 1.day) > smallest_datetime

DateTime object + hours|days|months from string method

I have problem with adding time values to DateTime object. Controller action gets values from form:
task_form.start_at - DateTime
task_form.remind_value - String, e.g. "2"
task_form.remind_space - String, e.g. "minutes", "hours", "days"
I want to send method like
remind_time = task_form.start_at + send("#{task_form.remind_value}.#{task_form.remind_space}")
but I get NoMethodError: undefined method '2.days'. There is any way to use method like that?
You are trying to invoke the method '2.days' on self (the controller, I guess), but you need to call the 'days' method on the integer object returned by task_form.remind_value
Try this:
remind_time = task_form.start_at + task_form.remind_value.send(task_form.remind_space)
Rails provides a Date#advance method:
start_at = DateTime.new(2014, 9, 18)
remind_value = "2"
remind_space = "days"
start_at.advance(remind_space.to_sym => remind_value.to_i)
#=> Sat, 20 Sep 2014 00:00:00 +0000

How do I get a comparison of Float & Nil to return a valid answer?

I have something like this:
good_attrs = %w(firm_size priority_level)
good_attrs.each do |attr|
if (score.send(attr) > max.send(attr))
max.send("#{attr}=", score.send(attr))
end
end
What happens, though, is that occassionally it may come across a Max record that looks like this:
#<Max:0x007fe01024b240> {
:id => 2,
:user_id => 1,
:firm_size => 101.0,
:priority_level => nil,
:created_at => Fri, 23 Nov 2012 01:55:53 UTC +00:00,
:updated_at => Fri, 23 Nov 2012 01:58:16 UTC +00:00
}
i.e. max.priority_level = nil.
So how do I modify my initial if statement to handle nil cases on both sides of the evaluation? i.e. if a score or max attribute is nil. Ideally, I would like it to be treated as 0 and proceed accordingly.
You can't compare nil with a Float.
In your case you can take advantage of the fact that nil.to_f == 0.0:
good_attrs = %w(firm_size priority_level)
good_attrs.each do |attr|
if score.send(attr).to_f > max.send(attr).to_f
max.send("#{attr}=", score.send(attr))
end
end
You can overload the attr_reader for priority_level and firm_size in Max
def priority_level
read_attribute(:priority_level).nil? ? 0 : super
end
You can alternatively set default values in an after_initialize block
after_initialize do
self.priority_level = 0 if self.priority_level.nil?
end

How can I find records from today, yesterday and so on with Ruby on Rails?

I want to find all records, say Posts, created today with Ruby on Rails, then all Posts created yesterday, and so on… how should I do?
Thank you,
Kevin
Try this:
#Today
Posts.find(:all, conditions: { :created_at => Date.today...Date.today + 1 })
#Yesterday
Posts.find(:all, conditions: { :created_at => Date.today - 1...Date.today })
Or this (preferable, in my opinion):
#Today
Posts.find(:all, conditions: ["DATE(created_at) = ?", Date.today] )
#Yesterday
Posts.find(:all, conditions: ["DATE(created_at) = ?", Date.today - 1] )
As a rule I store all dates on my server in UTC timezone and let the UI handle any timezone conversion.
To get the sort of query you are after to work correctly I had to massage the incoming date into a
UTC specific time range first.
require 'date'
class Post < ActiveRecord::Base
def self.created(a_date)
return Post.where(created_at: to_timerange(a_date))
end
private
def self.to_timerange(a_date)
raise ArgumentError, "expected 'a_date' to be a Date" unless a_date.is_a? Date
dts = Time.new(a_date.year, a_date.month, a_date.day, 0, 0, 0).utc
dte = dts + (24 * 60 * 60) - 1
return (dts...dte)
end
end
This then allows you to call
# today
posts = Post.created(Date.today)
# yesterday
posts = Post.created(Date.today - 1)
To query using a range I prefer the following:
yesterday = Date.yesterday
start = yesterday.beginning_of_day
#Fri, 27 Nov 2020 00:00:00 UTC +00:00
end = yesterday.end_of_day
# Fri, 27 Nov 2020 23:59:59 UTC +00:00 - the value here is one second before midnight
# meaning we should use an inclusive range using two dots:
range = start..end
Post.where(created_at: range)

Resources