Calculating the number of weeks in a year with Ruby
def num_weeks(year = Date.today.year)
Date.new(year, 12, 28).cweek # magick date!
end
long_iso_years = (2000..2400).select{|year| num_weeks(year) == 53}
Yields the same list as wikipedia
Rails number of weeks in month
i dont know exactly what you want... But maybe you want something like this:
(Time::days_in_month(05,2010).to_f / 7)
#> 4.42857142857143
Generate a list of commercial weeks falling between 2 dates in Ruby / Rails
Thank you to those who replied t. I've finally solved the problem like this:
campaign_weeks = []
campaign_start_date = "2014-07-23 06:59:00" # or any date
campaing_end_date = "2015-03-01 06:59:00" # or any date
start_year = DateTime.parse(campaign_start_date).cwyear
start_cweek_of_the_campaign = "%04d%02d" % [start_year, DateTime.parse(campaign_start_date).cweek]
end_year = DateTime.parse(campaing_end_date).cwyear
end_cweek_of_the_campaign = "%04d%02d" % [end_year, DateTime.parse(campaing_end_date).cweek]
if start_year == end_year
(start_cweek_of_the_campaign..end_cweek_of_the_campaign).each do |w|
campaign_weeks << ("%04d%02d" % [start_year, w])
end
else
(start_year..end_year).each do |y|
first_cweek_number_of_the_year = (y == start_year) ? start_cweek_of_the_campaign : 1
last_cweek_number_of_the_year = (y == end_year) ? end_cweek_of_the_campaign : DateTime.new(y, 12, 28).cweek
(first_cweek_number_of_the_year .. last_cweek_number_of_the_year).each do |w|
campaign_weeks << ("%04d%02d" % [y, w])
end
end
end
return campaign_weeks
Notes: 28th Dec always fall in the last cweek/iso-week of the year. last ISO week of the year is either 52 or 53.
Reference: http://en.wikipedia.org/wiki/ISO_week_date#Last_week
Got some hint from this answer: Calculating the number of weeks in a year with Ruby
Calculating the number of weeks in a month for a calendar in Rails
Ok, so some fiddling around lead me to this solution:
def week_rows
weeks.map {|week|
content_tag :div, class: week_classes do
week.map { |day| day_cell(day) }.join.html_safe
end
}.join.html_safe
end
def week_classes
classes = ['week']
classes << "wk_rows_4" if weeks_in_month == 4
classes << "wk_rows_5" if weeks_in_month == 5
classes << "wk_rows_6" if weeks_in_month == 6
classes.empty? ? nil : classes.join(" ")
end
def weeks_in_month
(0.5 + (date.end_of_month.day + date.at_beginning_of_month.wday).to_f / 7.0).round
end
It wasn't necessary to pass in (date)
as a parameter.
Given a timestamp, how to determine how many weeks ago?
If you just want to build a human-friendly string, I believe time_ago_in_words
is what you are after.
https://apidock.com/rails/ActionView/Helpers/DateHelper/time_ago_in_words
Otherwise, I would resort to something like the following:
(Time.new - user.created_at) / 1.week
If you want a more elegant solution, Subtract dates in Ruby and get the difference in minutes mentions the Time Difference gem for Ruby.
e.g.
TimeDifference.between(user.created_at.to_time, Time.now).in_weeks
Week number calculation in rails
You could compare the current calendar week with Date.current.cweek
(Reference) with your number.
require 'active_support/core_ext' # Already included in Rails
def calendar_week(week)
now = Date.current
year = now.cweek < week ? now.year : now.year + 1
Date.commercial(year, week, 1)
end
p calendar_week(49)
# => Mon, 02 Dec 2013
p calendar_week(1)
# => Mon, 30 Dec 2013 # don't know if that's the way calendar weeks are counted
p calendar_week(27)
# => Mon, 30 Jun 2014
How to calculate the current week in the month in Ruby
In order to handle the requirements you listed, I would suggest writing a helper function to get the number of the week in a month.
def get_month_week(date_or_time, start_day = :sunday)
date = date_or_time.to_date
week_start_format = start_day == :sunday ? '%U' : '%W'
month_week_start = Date.new(date.year, date.month, 1)
month_week_start_num = month_week_start.strftime(week_start_format).to_i
month_week_start_num += 1 if month_week_start.wday > 4 # Skip first week if doesn't contain a Thursday
month_week_index = date.strftime(week_start_format).to_i - month_week_start_num
month_week_index + 1 # Add 1 so that first week is 1 and not 0
end
This can then just be called like so:
get_month_week(Date.today)
If you really feel like monkey-patching is something you want, you can add to the Date class:
class Date
def month_week(start_day = :sunday)
week_start_format = start_day == :sunday ? '%U' : '%W'
month_week_start = Date.new(self.year, self.month, 1)
month_week_start_num = month_week_start.strftime(week_start_format).to_i
month_week_start_num += 1 if month_week_start.wday > 4 # Skip first week if doesn't contain a Thursday
month_week_index = self.strftime(week_start_format).to_i - month_week_start_num
month_week_index + 1 # Add 1 so that first week is 1 and not 0
end
end
And this can be called on a date or time like so:
Date.today.month_week
or
Time.current.to_date.month_week
I would advise against this since it may collide with other libraries or violate least-surprise for other developers working on the project.
Related Topics
In Ruby Why Won't 'Foo = True Unless Defined(Foo)' Make the Assignment
How to Get Class Instances in Ruby
How to Intercept Method Call in Ruby
Extract Single String from HTML Using Ruby/Mechanize (And Nokogiri)
How to Fix "Your Ruby Version Is 2.3.0, But Your Gemfile Specified 2.2.5" While Server Starting
Nested Models and Parent Validation
Dynamic Class Definition with a Class Name
Turning Long Fixed Number to Array Ruby
Why Aren't Do/End and {} Always Equivalent
Rails 'Parse_Query' Error on Server in Brand New App
Differencebetween Pluck and Collect in Rails
What Is the Purpose of "!" and "" at the End of Method Names
How to Replace a Hash Key with Another Key
Ruby Basic Data Type Conversion
What Is the "Right" Way to Iterate Through an Array in Ruby
Create a Devise User from Ruby Console