Forum: Ruby find monday of first week of the month

Announcement (2017-05-07): www.ruby-forum.com is now read-only since I unfortunately do not have the time to support and maintain the forum any more. Please see rubyonrails.org/community and ruby-lang.org/en/community for other Rails- und Ruby-related community platforms.
2ac62c781138715724898be538351f7a?d=identicon&s=25 Daniel Liebig (Guest)
on 2007-01-22 22:25
(Received via mailing list)
Hi,

im pretty new to Ruby and i tried to find out how to calculate the date
for the first monday of the first week of the month (i.e. this would be
2007-01-29 for Feb. 2007)
My approach is to get the weekday of the first day of the month and
calculate back from there. By getting the weekday i can tell how far to
calculate back (if necessary at all). If i'm calcualating back from
janurary, i also have to switch back the year.

So this is what i came out with:

     year = 2007
     month = 2

     # get the weekday of the first day of the month
     first_wd = Date.new(year, month, 1).wday

     # if weekday is sunday
     if first_wd == 0
       date_modifier = - 6

     #if weekday is monday
     elsif first_wd == 1
       date_modifier = 1

     # any other day
     else
       date_modifier = - ( first_wd - 1 )
     end

     #if i have to count back, swith month (and year) back
     if date_modifier < 0
       if month > 1
         month -= 1
       else
         month = 12
         year -= 1
       end
     end

     # get date with calculated modifier
     date_start = Date.new(year, month, date_modifier )

Ok, this works, but it seems pretty complicated to me. Is there a
smarter (and more readable) way to do this? As far as i know Ruby right
now, it's pretty unusual if an "easy" problem like this needs more than
three lines of code ;).

Thx for any help
Regards
Daniel
C5b0a0cf40eb23497068889c8fb20a18?d=identicon&s=25 lrlebron@gmail.com (Guest)
on 2007-01-22 23:05
(Received via mailing list)
You may want to try the chronic library

require 'chronic'
date_start = Chronic.parse("Monday of first week of February")
Aee77dba395ece0a04c688b05b07cd63?d=identicon&s=25 Daniel Berger (Guest)
on 2007-01-22 23:06
(Received via mailing list)
Daniel Liebig wrote:
> Hi,
>
> im pretty new to Ruby and i tried to find out how to calculate the date
> for the first monday of the first week of the month (i.e. this would be
> 2007-01-29 for Feb. 2007)

The first Monday in February is on January 29th? Hm, wait, I think I
understand what you're trying to say.

> My approach is to get the weekday of the first day of the month and
> calculate back from there. By getting the weekday i can tell how far to
> calculate back (if necessary at all). If i'm calcualating back from
> janurary, i also have to switch back the year.
>
> So this is what i came out with:

<snip>

require 'date'

date = Date.new(2007, 2)
p date.strftime("%Y-%m-%d") # 2007-02-01
date -= 1 until date.mday == 1
p date.strftime("%Y-%m-%d") # 2007-01-29

Regards,

Dan
Aee77dba395ece0a04c688b05b07cd63?d=identicon&s=25 Daniel Berger (Guest)
on 2007-01-22 23:10
(Received via mailing list)
lrlebron@gmail.com wrote:
> You may want to try the chronic library
>
> require 'chronic'
> date_start = Chronic.parse("Monday of first week of February")

Oh, now that is cool. :)

Dan
4299e35bacef054df40583da2d51edea?d=identicon&s=25 James Gray (bbazzarrakk)
on 2007-01-22 23:11
(Received via mailing list)
On Jan 22, 2007, at 4:05 PM, Daniel Berger wrote:

> require 'date'
>
> date = Date.new(2007, 2)
> p date.strftime("%Y-%m-%d") # 2007-02-01
> date -= 1 until date.mday == 1
> p date.strftime("%Y-%m-%d") # 2007-01-29

If you start with a Sunday you will end up with a Monday before
that.  Not sure that's what was intended.

James Edward Gray II
2ee1a7960cc761a6e92efb5000c0f2c9?d=identicon&s=25 William James (Guest)
on 2007-01-22 23:15
(Received via mailing list)
Daniel Liebig wrote:
> So this is what i came out with:
>
>      if date_modifier < 0
>
> Ok, this works, but it seems pretty complicated to me. Is there a
> smarter (and more readable) way to do this? As far as i know Ruby right
> now, it's pretty unusual if an "easy" problem like this needs more than
> three lines of code ;).
>
> Thx for any help
> Regards
> Daniel

def first_monday( year, month )
  date = Date.new( year, month, 1 )
  date - ( date.wday - 1 )
end
Ef3aa7f7e577ea8cd620462724ddf73b?d=identicon&s=25 Rob Biedenharn (Guest)
on 2007-01-22 23:27
(Received via mailing list)
On Jan 22, 2007, at 4:25 PM, Daniel Liebig wrote:

> So this is what i came out with:
>
>     if date_modifier < 0
>
> Ok, this works, but it seems pretty complicated to me. Is there a
> smarter (and more readable) way to do this? As far as i know Ruby
> right now, it's pretty unusual if an "easy" problem like this needs
> more than three lines of code ;).
>
> Thx for any help
> Regards
> Daniel
>

Your attempt isn't too far off from the Time#beginning_of_week from
ActiveSupport
      # File vendor/rails/activesupport/lib/active_support/core_ext/
time/calculations.rb, line 128
128:         def beginning_of_week
129:           days_to_monday = self.wday!=0 ? self.wday-1 : 6
130:           (self - days_to_monday.days).midnight
131:         end

Working just with a Date, that gives you:

 >> feb=Date.new(2007,2,1)
=> #<Date: 4908265/2,0,2299161>
 >> feb.to_s
=> "2007-02-01"
 >> feb -= (feb.wday != 0 ? feb.wday-1 : 6)
=> #<Date: 4908259/2,0,2299161>
 >> feb.to_s
=> "2007-01-29"

What about January 2008?

 >> jan08 = Date.new(2008,1,1)
=> #<Date: 4908933/2,0,2299161>
 >> jan08 -= (jan08.wday !=0 ? jan08.wday-1 : 6)
=> #<Date: 4908931/2,0,2299161>
 >> jan08.to_s
=> "2007-12-31"

You shouldn't have too much trouble wrapping that up into a nice
little method of your own.

-Rob

Rob Biedenharn    http://agileconsultingllc.com
Rob@AgileConsultingLLC.com
Aee77dba395ece0a04c688b05b07cd63?d=identicon&s=25 Daniel Berger (Guest)
on 2007-01-23 03:04
(Received via mailing list)
James Edward Gray II wrote:
> Not sure that's what was intended.
Whoops.

date = date.mday == 0 ? date += 1 : date -= 1 until date.mday == 1

Regards,

Dan
This topic is locked and can not be replied to.