Trip
Trip

Reputation: 27114

How do you find what week in a month a day is on?

I can't seem to wrap my head around what might be an easy question..

Suppose I have the date..

Fri, 14 Sep 2012 18:37:50 +0200

How do I find out what week this date is on for this month? Is it the 1st, the 2nd..? The third?

Thanks!

Upvotes: 5

Views: 5164

Answers (6)

Jason Noble
Jason Noble

Reputation: 3766

Why use a library? Ruby has it by default:

Week number:
The week 1 of YYYY starts with a Sunday or Monday (according to %U
  or %W).  The days in the year before the first week are in week 0.
    %U - Week number of the year.  The week starts with Sunday.  (00..53)
    %W - Week number of the year.  The week starts with Monday.  (00..53)

> Time.zone.parse("2012-01-01").strftime("%U")
=> "01" 

So, given that we can find what week a given date is in the year, we can do some math to figure out what week of the month it occurs in.

> week_of_year_for_first_of_month = Time.zone.parse("2012-07-01").strftime("%U").to_i
> week_of_target_date = Time.zone.parse("2012-07-14").strftime("%U").to_i
> week_occurs_in = week_of_target_date - week_of_year_for_first_of_month + 1
> week_occurs_in # => 2

Or a method:

def week_of_month_for_date(date)
  my_date = Time.zone.parse(date)
  week_of_target_date = my_date.strftime("%U").to_i
  week_of_beginning_of_month = my_date.beginning_of_month.strftime("%U").to_i
  week_of_target_date - week_of_beginning_of_month + 1
end

> week_of_month_for_date("2012-07-14") # => 2 
> week_of_month_for_date("2012-07-15") # => 3 

Upvotes: 11

imnotquitejack
imnotquitejack

Reputation: 91

I was challenged with answering "June 30th, 2017 is the nth Friday in June, 2017".

I solved this by building an array of all of the day names (Monday, Tuesday, etc) accrued up until the target date, and counting how many matched.

target_date = Date.new(2017, 6, 30)
(1..target_date.day).select do |day_of_month|
  Date.new(target_date.year, target_date.month, day_of_month).strftime('%A') == target_date.strftime('%A')
end.length

Upvotes: 1

Try this, find the week of a_date (considering first week is 1, and first day of week is monday):

week = (((a_date.mday + Date.new(a_date.year, a_date.month, 1).wday - 1) / 7) + 1)

Upvotes: 0

Ryan McGeary
Ryan McGeary

Reputation: 239914

The week_of_month gem looks like it might be a bit overkill. That implementation uses a lot of array splitting and Array.include? checks.

Instead, here's a module that you can mixin to Date and Time to get the desired behavior.

require "active_support/core_ext/date"
require "active_support/core_ext/time"

module WeekCalculator
  def week_of_year(mondays = false)
    # Use %U for weeks starting on Sunday
    # Use %W for weeks starting on Monday
    strftime(mondays ? "%W" : "%U").to_i + 1
  end

  def week_of_month(mondays = false)
    week_of_year(mondays) - beginning_of_month.week_of_year(mondays) + 1
  end
end

class Date
  include WeekCalculator
end

class Time
  include WeekCalculator
end

Date.new(2014, 1, 1).week_of_year            # => 1
Date.new(2014, 1, 1).week_of_month           # => 1
Date.new(2014, 7, 1).week_of_year            # => 27
Date.new(2014, 7, 1).week_of_month           # => 1

Date.new(2014, 7, 27).week_of_year           # => 31
Date.new(2014, 7, 27).week_of_month          # => 5
Date.new(2014, 7, 27).week_of_year(:monday)  # => 30
Date.new(2014, 7, 27).week_of_month(:monday) # => 4

Upvotes: 2

Kelvin
Kelvin

Reputation: 20857

Note that it depends how you count weeks. Let's say June 1 is on a Saturday. What week do you consider June 2 to be on? It might be the second week, or maybe it's the first if you consider a countable week to contain at least 4 days.

Or perhaps, given that June 2 is a Sunday, what's the week number of that Sunday? It's unambiguously the first Sunday. If this is what you mean, then it's actually simple. Dates 1 through 7 are always the first [weekday name] in the month. Dates 8-14 are always second. And so on. All you have to do is build a hash, and it will work for any month.

Upvotes: 3

jornak
jornak

Reputation: 478

sachin87 has a library for determining such a thing.

Upvotes: 8

Related Questions