How to Get the Number of Days in a Given Month in Ruby, Accounting for Year

How to get the number of days in a given month in Ruby, accounting for year?

This is the implementation from ActiveSupport (a little adapted):

COMMON_YEAR_DAYS_IN_MONTH = [nil, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31]

def days_in_month(month, year = Time.now.year)
return 29 if month == 2 && Date.gregorian_leap?(year)
COMMON_YEAR_DAYS_IN_MONTH[month]
end

how to get the number of days elapsed this year?

In Rails Active Support adds #beginning_of_year method to Date:

(Date.today - Date.today.beginning_of_year).to_i

How to build a monthly range that takes in account the number of days of each month?

I think you can use either active support:

require 'active_support/time'
start_date = Date.parse('2019-10-31')
12.times.map { |i| start_date + i.month }

=> [
Thu, 31 Oct 2019,
Sat, 30 Nov 2019,
Tue, 31 Dec 2019,
Fri, 31 Jan 2020,
Sat, 29 Feb 2020,
Tue, 31 Mar 2020,
Thu, 30 Apr 2020,
Sun, 31 May 2020,
Tue, 30 Jun 2020,
Fri, 31 Jul 2020,
Mon, 31 Aug 2020,
Wed, 30 Sep 2020
]

or adjust: #next_month:

require 'date'
Date.parse('2019-10-31').next_month # => Sat, 30 Nov 2019

Ruby convert decimal duration (day|week|month|year) to end date

I'd say your best option is to use Ruby's date methods to advance time based on the whole number of the decimal, then calculate how many seconds your fraction is of your current interval.

So for 1.998 months, advance time 1 month. Find the current month you are in and get the .998 of the seconds in that month (i.e. for July, 31x24x60x60x.998) and then advance time that many seconds.

get count of users for previous day week or month in ruby on rails

I would try something like this:

For example if you want to selecet the Users created in the last hour:

  @date_start = DateTime.now
@date_end = @date_start - 1.hour
@users = User.where(:created_at => @date_end..@date_start)

how to find number of working days for particular month in rails

You might want to take a look at business_time

Example:

4.business_days.from_now
8.business_days.after(some_date)

Monthly schedule that catches ends of the month

This passes all my specs, but is fugly and probably breaks for schedules longer than a year (which I don't care about yet).

class LeasePaymentSchedule

def self.monthly(a bunch of args)
case start_day

when 31
schedule = IceCube::Schedule.new(start, scheduler_options) do |s|
s.add_recurrence_rule IceCube::Rule.monthly.day_of_month(-1).until(end_time)
end

when 30,29
schedule = IceCube::Schedule.new(start, scheduler_options) do |s|
s.add_recurrence_rule IceCube::Rule.monthly.day_of_month(start_day).until(end_time)
end

schedule.all_occurrences.each do |o|
next unless [1,3,6,8,10].include? o.month
missed = (o + 1.month).yday
# Probably breaks for durations longer than 1 year
schedule.add_recurrence_rule IceCube::Rule.yearly.day_of_year(missed).count(1)
end

else
schedule = IceCube::Schedule.new(start, scheduler_options) do |s|
s.add_recurrence_rule IceCube::Rule.monthly.day_of_month(start_day).until(end_time)
end
end
schedule
end
end

So many specs:

Finished in 4.17 seconds
390 examples, 0 failures

-

shared_examples_for :a_schedule do
it 'returns an IceCube Schedule' do
schedule.should be_a IceCube::Schedule
end
it 'should start on the correct day' do
schedule.start_time.should eq expected_start
end
it 'has the right number of occurrences' do
schedule.all_occurrences.size.should eq expected_occurrences
end
end

describe :monthly do
let(:expected_occurrences) { 12 }
let(:expected_start) { date.next_month.beginning_of_day }
let(:schedule) { LeasePaymentSchedule.monthly }

before do
Date.stub(:today).and_return(date)
end

shared_examples_for :on_the_28th do
let(:date) { Time.parse "#{year}-#{month}-28" }
it_behaves_like :a_schedule
end

shared_examples_for :on_the_29th do
let(:date) { Time.parse "#{year}-#{month}-29" }
it_behaves_like :on_the_28th
it_behaves_like :a_schedule
end

shared_examples_for :on_the_30th do
let(:date) { Time.parse "#{year}-#{month}-30" }
it_behaves_like :on_the_29th
it_behaves_like :a_schedule
end

shared_examples_for :on_the_31st do
let(:date) { Time.parse "#{year}-#{month}-31" }
it_behaves_like :on_the_30th
it_behaves_like :a_schedule
end

shared_examples_for :the_whole_year do
context :february do
let(:month) { 2 }
it_behaves_like :on_the_28th
end
[ 4, 7, 9, 11 ].each do |month_num|
let(:month) { month_num }
it_behaves_like :on_the_30th
end
[ 1, 3, 5, 6, 8, 10, 12].each do |month_num|
let(:month) { month_num }
it_behaves_like :on_the_31st
end
end

context :a_leap_year do
let(:year) { 2012 }
context :february_29th do
let(:month) { 2 }
it_behaves_like :on_the_29th
end
it_behaves_like :the_whole_year
end

context :before_a_leap_year do
let(:year) { 2011 }
it_behaves_like :the_whole_year
end

context :nowhere_near_a_leap_year do
let(:year) { 2010 }
it_behaves_like :the_whole_year
end

end

How can I get the 15th and last day of each month?

I'm not sure if this will work with Rails 4:

start_date = Date.today
# => Wed, 06 Nov 2013
mid_month = (start_date + 1.month).beginning_of_month + 14
# => Sun, 15 Dec 2013
end_month = (start_date + 1.month).end_of_month
# => Tue, 31 Dec 2013

How to output a date range for each quarter of a year in Ruby?

This should work (based on month_ranges, i.e. last quarter comes first):

def quarter_ranges
years.flat_map { |y|
3.downto(0).map { |q|
Date.new(y, q * 3 + 1, 1)..Date.new(y, q * 3 + 3, -1)
}
}
end

Or a bit more verbose and maybe easier to understand:

def quarter_ranges
years.flat_map { |y|
[
Date.new(y, 10, 1)..Date.new(y, 12, -1),
Date.new(y, 7, 1)..Date.new(y, 9, -1),
Date.new(y, 4, 1)..Date.new(y, 6, -1),
Date.new(y, 1, 1)..Date.new(y, 3, -1)
]
}
end


Related Topics



Leave a reply



Submit