How do I get a Date from a week number? - ruby-on-rails

I want to find all items created in a given week, and pass in a week number param. (created_at is a normal timestamp.)
Given a week number, what is the easiest way to find a date in that particular week?
(Any date in the week will do, as I will use beginning_of_week and end_of_week in the scope.)

You can get Date objects representing the beginning and end of your week using the commercial method:
week = 41;
wkBegin = Date.commercial(2010, week, 1)
wkEnd = Date.commercial(2010, week, 7)
Now do your find:
Item.find(:all, :conditions->:create_date=>wkBegin..wkEnd.end_of_day)

Assuming you mean "a given week number in the current year", you can do the following:
2.weeks.since(Time.gm(Time.now.year))
=> Fri Jan 15 00:00:00 UTC 2010
Substitute (week_number - 1) for the 1 in the above, and you'll get a date in the desired week.

Related

count how many specific days are in a time period

I want to count say how many Mondays we have from 2022-02-01 - 2022-03-01. I found smth like this:
=SUMPRODUCT(WEEKDAY(B4:C4)=2) - B4 and C4 are the dates
But it returns 0. I assume it only checks if specific date is the specific day. Any ideas how I can do this but for a date range? So how count how many Mondays there are in February
I also found this
=NETWORKDAYS.INTL(B4;C4;"1000000")
but this returns 25
You can take advantage of the NETWORKDAYS.INTL function by using the string method to make all the days as weekend except for Monday.
The String method states:
weekends can be specified using seven 0’s and 1’s, where the first number in the set represents Monday and the last number is for Sunday. A zero means that the day is a work day, a 1 means that the day is a weekend. For example, “0000011” would mean Saturday and Sunday are weekends.
In this case since you only want to know the Mondays, the string would be "0111111" and the function would look like:
=NETWORKDAYS.INTL(StartDate,EndDate,"0111111")
I think this is right. It's counting inclusively so you would get five Mondays starting on Monday 7th Feb 2022 and ended on Monday 7th March 2022 for example.
=floor((B2-(A2+7-weekday(A2,12)))/7)+1
where A2 and B2 contain the start date end end date.
Obvs nul points for me again but for the record this could be generalised if you put the day number in C2 (e.g. 1 if you want to find Sundays, 2 for Mondays):
=floor((B2-(A2+7-weekday(A2,10+C2)))/7)+1

EOMONTH returns the 1st day of the next month for months with 30 days

When I use the formula below the results of the EOMONTH function
returns the start of the next month for any month with 30 days instead of the last day of the specified month. The month and years are correct, so I'm pretty sure it's EOMONTH when used in another function.
For example,the results in B3 should be "11/31/1965" but it returns "12/1/1965".
=DATE(YEAR(B2),MONTH(B2)+6,DAY(TEXT(EOMONTH(MONTH(B2)+6,0))))
I have tried subtracting a day, but it returns the end-of-month -1 for months with 31 days (30). So I have the same problem in the other case.
I have also used IFS() to account for months with 30 days, and it miscalculates the date the same way.
=IFS( MONTH(B2)+6 = 4,DATE(YEAR(B2),MONTH(B2)+6,DAY(EOMONTH(MONTH(B2)+6,0))-2) ,
MONTH(B2)+6 =
6,DATE(YEAR(B2),MONTH(B2)+6,DAY(EOMONTH(MONTH(B2)+6,0))-2) ,
MONTH(B2)+6 =
9,DATE(YEAR(B2),MONTH(B2)+6,DAY(EOMONTH(MONTH(B2)+6,0))-2) ,
MONTH(B2)+6 =
11,DATE(YEAR(B2),MONTH(B2)+6,DAY(EOMONTH(MONTH(B2)+6,0))-2) ,
TRUE ,DATE(YEAR(B2),MONTH(B2)+6,DAY(EOMONTH(MONTH(B2)+6,0)) ) )
The EOMONTH function by itself where I just pass in the date as a string works correctly (column F).
Any Idea on what I'm doing wrong?
Thanks in advance.
Yes, as #player0 has explained, you can't just add something to a month and feed it into eomonth. Try putting
=eomonth(month(B2)+6,0)
into B3 (formatted as a date).
You get
1/31/1900
Why? month(b2)+6 gives 11 (which is just a number). Dates in google sheets are represented as days since 12/31/1899. So 11 formatted as a date gives 1/11/1900. Applying eomonth to that gives the last day of January 1900, which is the 31st. Feeding that into your formula would give 11/31/65, but that date doesn't exist, so you get 12/1/65.
If you want to go forward 6 months and then get the last day of the month, you need
=eomonth(date(year(B2),month(B2)+6,1),0)
You can also use the Edate function, which does not roll over into the first day of the next month:
=eomonth(edate(B2,6),0)
EOMONTH does not understand MONTH. instead, it converts it into date. to use EOMONTH you need to supply it with valid date
=EOMONTH(B2, 0)

.change function is not working for Dates for even number of months in ruby

Hi I have define this method
def change_date
date = Date.today
start_date = date.change(year: 2015, month: (2 * 3)).at_beginning_of_quarter
p 'aaaaaa'
p start_date
end
give me invalid date error .change is not working or am I doing it in a wrong way please guide me how to solve this. Thanx in advance.
This is because the month you are specifying doesn't have the current day.
I mean the current month (July) has 31 days but the month you're setting (June) has only 30 days. You can change your code like so:
# in Rails:
date = Date.today.beginning_of_month # or Date.today.change(day: 1)
Then chain your 'change' in front of the date variable.
This actually happens, because today is the 31 of July, and not all months have 31 days in it, for example June, the 6th month, has only 30 days in it.

Convert week number to date range with Saturday as beginning_of_week

I need to use Saturday as the week start and calculate the beginning and the end of week from week numbers. I need week 53 to be properly accounted for as well.
Date.beginning_of_week = :saturday
works fine, but I have not found a way to generate week start and end dates only from a year and week number. Date.commercial is the only method I have been able to use thus far to convert a week number and year only to a date. I have been unable to get Date.commercial to recognize Saturdays as the week start.
I need to use Saturday as the week start and calculate the beginning and the end of week from week numbers.
Given an instance of Date representing the first Saturday, and the week number, this is quite simple, unless I'm missing something.
def beginning_of_week(first_saturday, week_num) {
return first_saturday + (7 * week_num.to_i).days
}
The days method comes from activesupport.

Rails: Is there away to get the Date object that is the closest Monday to today?

Given a date, how do I find the nearest Monday in Rails?
I know I can do things like:
Date.tomorrow
Date.today
Is there something like Date.nearest :monday ?
The commercial method on the Date object will let you do this. This example will get you the next Monday.
Date.commercial(Date.today.year, 1+Date.today.cweek, 1)
If you need the next or previous Monday, whichever is closest, you can do:
Date.commercial(Date.today.year, Date.today.cwday.modulo(4)+Date.today.cweek, 1)
I can't execute this right now, so forgive me if there are syntax errors.
It's a little bit tricky, but not so hard to calculate.
Use ActiveSupport::DateAndTimeCalculations#end_of_week to calculate end of a week, this method accepts a start_day parameter that is used to indicate start day of the week (it's :monday by default). They even have implemented sunday method.
The trick is the following: if you want to calculate closest Monday, you may calculate it as a end of the week which starts on Tuesday (Tue => 1st day, Wed => 2nd day, ..., Mon => 7th day which is also end of the week).
So all you need to do is:
# it will return current date if today is Monday and nearest Monday otherwise
Date.today.end_of_week(:tuesday)
I know this is an old thread but it's always nice to keep it current for future seekers.
Let's assume today is say Friday the 19th of August. All I do to get my nearest Monday is this:
monday = Date.today.monday
Then from there you can go back a week or forward a week like this:
last_monday = monday.last_week
next_monday = monday.next_week
Assuming you want both directions: Date.today.beginning_of_week + 7*(Date.today.wday/5)
Untested, so you might need to finetune, but here you go:
def Date.nearest_monday
today = Date.today
wday = today.wday
if wday > 4 # over the half of the week
today + (7 - wday) # next monday
else
today - (1 + wday) # previous monday
end
end

Resources