Get calendar week numbers in requested month in RoR - ruby-on-rails-3

I've been searching for hours now and I just can't find the right answer.
Hope you can help me out.
Ruby: 1.9.3p194
Rails: 3.2.8
Goal:
1.9.3p194 :001 > get_weeknumbers_in_month 1, 2012
=> [1, 2, 3, 4]
1.9.3p194 :002 > get_weeknumbers_in_month 2, 2012
=> [5, 6, 7, 8]
1.9.3p194 :003 > get_weeknumbers_in_month 3, 2012
=> [9, 10, 11, 12, 13]
1.9.3p194 :004 > get_weeknumbers_in_month 4, 2012
=> [14, 15, 16, 17]
So, I actually want an array of calendar week numbers when the method get_weeknumbers_in_month is called.
Research:
To get the month numbers from a date:
DateTime.parse("2012-01-10").month
=> 1
To get the number of days in a month:
Time::days_in_month(1, 2012)
=> 31
To get the calendar week number of a date:
DateTime.parse("2012-04-12").strftime("%W").to_i
=> 15
Can someone please help me with this issue?
Thanks in advance.

If I understand, you've almost done!
the last is to calculate first and last dates for month, isn't it?
So something like next may work (not tested)
def get_weeknumbers_in_month(month, year)
first_week_num = Date.new(year,month,1).strftime("%U").to_i
last_week_num = Date.new(year,month,1).end_of_month.strftime("%U").to_i
(first_week_num..last_week_num).to_a
end

Related

How to group into 2 week increments by created_at [ruby]

I have survey responses that I need to display in 2 week increments based on the created_at date. The output should be something like:
{10/1 : 4
10/15: 6
10/29: 3}
...where the first week is created from the earliest created_at date in the survey responses and the same for the last, but the latest created_at. I've seen things like group_by{ |s| s.created_at.month} but not something for every other week, starting on the Monday of the week. Any help would be much appreciated!
You could calculate the number of days between the current record and the oldest and then use modulo 14:
oldest_date = YourModel.minimum(:created_at).to_date
your_relation.group_by { |record|
(record.created_at.to_date - oldest_date).modulo(14)
}
You could define a method returning the year and the week range, for example:
def by_year_and_by_two_weeks(my_date)
wk = my_date.strftime("%W").to_i/2
wks = [wk, wk.odd? ? wk+1 : wk - 1].sort # <== adjust this
[my_date.year, wks]
end
The %W in rails uses monday as the first day of the week.
So, when you have your object:
object.created_at #=> 2021-09-19 08:58:16.78053 +0200
by_year_and_by_two_weeks(object.created_at) #=> [2021, [17, 18]]
Then you can use the method for grouping.
objects.group_by { |d| by_year_and_by_two_weeks(d.created_at) }
This is an example of result after values transformation to make it readables:
{[2021, [20, 21]]=>[2021-10-14 09:00:17.421142 +0200, 2021-10-15 09:00:17.421224 +0200, 2021-10-06 09:00:17.421276 +0200, 2021-10-10 09:00:17.421328 +0200], [2021, [18, 19]]=>[2021-09-22 09:00:17.421385 +0200]}
Of course you can change the by_year_and_by_two_weeks return value as it best fits for you.
Your requirements:
You want to group on the monday of the starting biweekly period.
You want the Hash key of the group to be the date of that monday.
I will also add another future-proofing requirement:
The start and end dates can be anywhere, even accross year boundaries.
If we take these requirements, and then utilize the modulo idea from spickermann, we can build it like this:
start_date = first_item.created_at.to_date.prev_occurring(:monday)
your_items.group_by { |item|
item_date = item.created_at.to_date
days_from_start = item_date - start_date
biweekly_offset = days_from_start.modulo(14)
biweekly_monday = item_date - biweekly_offset
biweekly_monday
}
Example:
test_dates = [
Date.new(2021, 10, 1),
Date.new(2021, 10, 6),
Date.new(2021, 10, 10),
Date.new(2021, 10, 13),
Date.new(2021, 10, 20),
Date.new(2021, 10, 31)
]
start = test_dates.first.prev_occurring(:monday)
pp test_dates.group_by { |date|
days_from_start = date - start
biweekly_offset = days_from_start.modulo(14)
biweekly_monday = date - biweekly_offset
biweekly_monday
}
Output:
{ Mon, 27 Sep 2021 => [Fri, 01 Oct 2021, Wed, 06 Oct 2021, Sun, 10 Oct 2021],
Mon, 11 Oct 2021 => [Wed, 13 Oct 2021, Wed, 20 Oct 2021],
Mon, 25 Oct 2021 => [Sun, 31 Oct 2021] }

SQL converting number of days to weeks

I have a SQL table with a column that says number of days, and contains entries like 23, 26, 45, etc...
I am trying to convert each entry to a "week number". In essence, what I mean is that if my day entry is between 0 and 6, then, this is Week 1, if it is 7 and 13, then this is Week 2, 14 and 20, week 3, etc... Is there an "efficient" way to do this in SQL?
Thanks.
Thomas.
You need just the standard divide function. It ignores the remainder:
SELECT (Days / 7) + 1
You can try this and no need to add +1;
SELECT (Days / 7.00)

SSRS parameter default to most recent 1st April

I have a requirement for an SSRS parameter that will be for a start date of the most 1st April, so today it will report from 1/4/2015 with 10 weeks data, but after the 1/4/16 it will default to 1/4/16.
Can anyone help with this please?
I can find most recent month, or current month etc, but this one is a little tricky. Thankyou.
I am using SQL Server 2012 and Visual Studio 2010
You could use the following expression:
=IIF(Today() >= DateSerial(Year(Today()), 4, 1), DateSerial(Year(Today()), 4, 1), DateSerial(Year(Today()) - 1, 4, 1))
The idea is to check if the 1st of April of the current year has been reached (Today() >= DateSerial(Year(Today()), 4, 1)).
If yes, take the 1st of April of the current year: DateSerial(Year(Today()), 4, 1)
If no, take the 1st of April of the previous year: DateSerial(Year(Today()) - 1, 4, 1)

date select showing days before and after given date

I want to have a drop down on a form that shows in plain English "1 day before, 2 days before" etc a given date as well as "1 days after, 2 days after".
How can I do this with Rails date_select?
Thanks
Ok I am creating my own as follows but am a bit stuck:
<%= select_tag(:board,options_for_select([["On the Birthday", 0], ["1 Day Before", -1], ["Two Days Before", -2], ["Three Days Before", -3]]), { :class => "default" }) %>
Now what I want to do is to show the number of days the user has saved. So how can I program or set the select so it knows which value to select.
I have the delivery date saved in a table and can access it as follows:
#board.deliver_on
Thanks.
Put simply: you can't do it with a date_select. You would need to build it using either the select or collection_select helpers and work out the values for the dates yourself. There is no helper in Rails to do that as far as I am aware.

calculate difference in time in days, hours and minutes

UPDATE: I am updating the question to reflect the full solution. Using the time_diff gem Brett mentioned below, the following code worked.
code:
cur_time = Time.now.strftime('%Y-%m-%d %H:%M')
Time.diff(Time.parse('2011-08-12 09:00'), Time.parse(cur_time))
Thanks, Brett.
Without using a external gem, you can easily get differences between dates using a method like this:
def release(time)
delta = time - Time.now
%w[days hours minutes].collect do |step|
seconds = 1.send(step)
(delta / seconds).to_i.tap do
delta %= seconds
end
end
end
release(("2011-08-12 09:00:00").to_time)
# => [7, 17, 37]
which will return an array of days, hours and minutes and can be easily extended to include years, month and seconds as well:
def release(time)
delta = time - Time.now
%w[years months days hours minutes seconds].collect do |step|
seconds = 1.send(step)
(delta / seconds).to_i.tap do
delta %= seconds
end
end
end
release(("2011-08-12 09:00:00").to_time)
# => [0, 0, 7, 17, 38, 13]
I've used time_diff to achieve this sort of thing easily before, you may want to check it out.