How to calculate the sum of array inside hash ruby - ruby-on-rails

Hai i am creating a json file with my data and i need to calculate the hours before i save it into the database
I am assigning that hash into a variable payload and tried doing this but it returns me an error TypeError (no implicit conversion of Symbol into Integer):
total_hours = #payload.sum{|activity| activity[:hours].to_f}
Hash before converting to json
{:activities=>
[{:project=>1,
:activity=>"my activity",
:hours=>0.2e1,
:date=>Sat, 10 Aug 2019 00:00:00 UTC +00:00},
{:project=>2,
:activity=>"Tester",
:hours=>0.2e1,
:date=>Thu, 01 Aug 2019 00:00:00 UTC +00:00},
{:project=>2,
:activity=>"Tester",
:hours=>0.3e1,
:date=>Thu, 01 Aug 2019 00:00:00 UTC +00:00}]}
I need to sum the hours of my array which is inside the hash. Thanks

If you are using Rails, here is a short way:
#payload[:activities].pluck(:hours).reduce(:+)

You should use:
total_hours = #payload[:activities].sum{|activity| activity[:hours].to_f}
You see, what you're wanting to do is, essentially:
[
{
:project=>1,
:activity=>"my activity",
:hours=>0.2e1,
:date=>Sat, 10 Aug 2019 00:00:00 UTC +00:00
},
{
:project=>2,
:activity=>"Tester",
:hours=>0.2e1,
:date=>Thu, 01 Aug 2019 00:00:00 UTC +00:00
},
{
:project=>2,
:activity=>"Tester",
:hours=>0.3e1,
:date=>Thu, 01 Aug 2019 00:00:00 UTC +00:00
}
].sum{|activity| activity[:hours].to_f}
But, you're calling .sum on the #payload variable, which is a hash. What you want is the value of the hash that is associated with the key :activities. Thus, you need to call .sum on #payload[:activities] where #payload[:activities] returns the array above.

Related

Parse Time in Ruby

I'm trying to parse this date Wed, 17 Feb 2021 13:00:00 +0100 into this 2021-02-17 13:00:00.000000000 +0100.
And I've tried using this Time.strptime(current_time.to_s, '%Q'), (where current_time it's the date above) but I get 1970-01-01 01:00:02.021 +0100
But I don't understand why I get another date, could you help me? Thanks!
I'm trying to parse this date Wed, 17 Feb 2021 13:00:00 +0100 [...]
You seem to already have an instance of Time: (or ActiveSupport::TimeWithZone which is Rails' drop-in replacement with better timezone support)
current_time = Time.current
#=> Thu, 19 May 2022 10:09:58.702560000 CEST +02:00
In this case, there's nothing to parse. You just have to format it via strftime the way you like:
current_time.strftime('%F %T.%N %z')
#=> "2022-05-19 10:09:58.702560000 +0200"
Parsing is only needed when you have a string representation that you want to turn into a Time object, e.g.: (using Rails' Time.zone.parse variant)
time_string = 'Thu, 19 May 2022 10:09:58.702560000 CEST +02:00'
time_obj = Time.zone.parse(time_string)
#=> Thu, 19 May 2022 10:09:58.702560000 CEST +02:00
time_obj.class
#=> ActiveSupport::TimeWithZone

How do I convert a `DateTime` to the corresponding date and time in Berlin?

Given a (UTC) DateTime object, how can I get the corresponding time in Berlin, in CET or CEST, depending on the date?
Examples for the desired "convert" function:
convert(DateTime.new(2018, 07))
=> Sun, 01 Jul 2018 02:00:00 +0200
convert(DateTime.new(2018, 12))
=> Sat, 01 Dec 2018 01:00:00 +0100
Try this
require 'tzinfo'
timezone = TZInfo::Timezone.get('Europe/Berlin')
local_time = timezone.utc_to_local(utc_time)
That even works without Rails.

How does Rails handle comparison between TimeWithZone and Date objects?

This could introduce subtle "bugs" (perceived inconsistencies), like the following:
>> Time.zone.parse('Tue, 01 Aug 2017 00:00:00 CEST +02:00') < Date.new(2017,8,1)
=> true
It seems as if Rails converts the Date to a DateTime or TimeWithZone object with '00:00:00 UTC', hence the result. Like this:
>> Date.new(2017,8,1).to_datetime
=> Tue, 01 Aug 2017 00:00:00 +0000
That would explain it. But I would like to know how Rails actually does this, and what type of object it converts it to in the process, to be sure. I didn't find it in the API docs, or the source, but maybe someone can give a step by step explanation.
The source I looked through was: compare_with_coercion
PS: To me it would seem saner that in this type of comparison that Rails would actually convert the TimeWithZone object to a Date object instead, thus resulting in only the date portions to be compared, so that:
>> Time.zone.parse('Tue, 01 Aug 2017 00:00:00 CEST +02:00') == Date.new(2017,8,1)
=> true
Ref:
DateTime API doc
Date API doc

Ruby parse DateTime with variable

I'm trying to parse a specific hour of a specific date. When I put the date directly as an argument, it works fine, but when I create a variable and put it in the argument it returns the current date.
Why is that?
NOTE: the variable time is 9pm and I need to parse 9pm of 12 March 2016.
datetime = DateTime.new(2016,3,12,9)
=> Sat, 12 Mar 2016 09:00:00 +0000
DateTime.parse("sat 12 march 2016 9pm")
=> Sat, 12 Mar 2016 21:00:00 +0000
DateTime.parse("datetime 9pm")
=> Mon, 14 Mar 2016 21:00:00 +0000
In your third call, you use the literal string "datetime" rather than the value of your datetime variable. You can use string interpolation to use the variable's value:
DateTime.parse("#{datetime} 9pm")
In this case, the "9pm" is ignored since it doesn't make sense added to the end of an existing date but this is why the initial attempt wasn't working. Interpolation is generally a solution for using a variable's value rather than its name.
If your goal is to change the time of an existing date, use the change method:
datetime.change(hour:21)
You can also try this
date = Date.new(2016,3,12)
DateTime.parse("#{date} 9pm")
## Output
Sat, 12 Mar 2016 21:00:00 +0000
OR
datetime = DateTime.new(2016,3,12,9)
DateTime.parse((datetime + 12.hours).to_s)
## Output
Sat, 12 Mar 2016 21:00:00 +0000
OR
DateTime.parse((datetime + 12.hours).to_s).strftime("%a, %d %b %Y %I:%M %p")
## Output
Sat, 12 Mar 2016 09:00 PM

Invalid date getting displayed in rails

I know it is common error but I could not resolve it even after trying those answers.
Through the rest api I am sending some parameters inculdes dates. I am recieving all the data in the method where I want but when I am trying to parse Date it throws error of invalid date.
Here are my parameters that I am recieving
{"uid"=>"1", "user"=>"abc.a#abc.com", "from"=>"Mon Nov 3 24:59:12 CET 2014", "to"=>"Tue Nov 11 24:59:12 CET 2014"}
and Date format is
Mon Nov 3 24:59:12 CET 2014
but it is throwing error on parsing on line below
fr = DateTime.parse(params[:from]) unless params[:from].empty?
I tried strptime as well but did not work.
Imp points is I need hour also for later processing. Thanks
what you are doing wrong is parsing DateTime while it is just date and should be parsed as one of the following ways:
1.
>> fr = params[:from].to_date unless params[:from].empty?
=> Mon, 03 Nov 2014
2.
>> fr = Date.parse(params[:from]) unless params[:from].empty?
=> Mon, 03 Nov 2014
You have 24:59 which is invalid time. Anyway, use strptime:
DateTime.strptime("Mon Nov 3 22:59:12 CET 2014", "%a %b %e %T %Z %Y")
#=> Mon, 03 Nov 2014 22:59:12 +0100

Resources