www.flickr.com

Our big project at Panoctagon has a lot to do with time and dates, so we’ve been developing a series of Rails plugins that make our jobs easier. I had a lot of fun building this one, and I could see other people finding this interesting, so we decided to open source this one. I think it’d make a great addition to Rails core (if I do say so myself :P), but I am not really up to all the effort involved. Instead I created a simple to use, documented, and tested plugin that works with Rails!

So what does it do? Basically, it makes date month values more meaningful by adding a new Month class that can do complex(ish) calculations against the days of the month for you. It also allows you to treat a Month as an enumerable container, allowing you to iterate through the days of the month like an array.

Lets peek at some example snippets:

Getting The First Tuesday of September 2009

1
2
    Month.september(2009).first_tuesday #=> Date object
    Month.new(9,2009).first(:tuesday) #=> Date object

Getting Every Friday in August 2008

1
2
    Month.august.every_friday #=> Array of Date objects
    Month.new("August").every(:friday) #=> Array of Date objects

Getting Every Thursday and Saturday in June 2007

1
2
    Month.june(2007).every_thursday_and_saturday #=> Hash of Arrays of Date objects
    Month.new("June",2007).every(:thursday,:friday) #=> Hash of Arrays of Date objects

Getting The Last Monday in April 2005

1
2
    Month.april(2005).last_monday #=> Date object
    Month.new("April",2005).last(:monday) #=> Date object

Enumerating Through the Month of August 2008

1
2
3
4
5
   month = Time.now.month #=> Month object of the current time requested
   month.each do |day|
     day.to_s #=> Week day name ie: Saturday, Sunday, etc.
     day.to_i #=> Date value in context of the month ie: 1..31
   end

Other Odds and Ends

1
2
3
4
5
  Month.april.size #=> total number of days in that month
  Month.august.next #=> returns a month object populated with August
  Time.now.month #=> returns the current month in context to the #now response
  Month[5] #=> May Month object access as array index
  Month[:april] #=> April month object access as hash key

So, as you can see, it saves a lot of time and calculations and keeps it easy for you to treat months as essentially a container! Really useful for doing complex calculations against dates.

If you would like to use my plugin, feel free, I’ve released it under MIT, and its located at my github account. Please give me some props if you do, or send me a line.

If you are interested in my rdoc documentation, check our company’s documentation server. Let me know what you guys think!


Comments

Name (required)

Email (required)

Website

Speak your mind

8 Comments so far

  1. Matt Mower on August 15, 2008 12:40 am

    Your class looks useful but I wonder why you’d limit it by making it a plugin rather than releasing it as a gem.

    Regards,

    Matt

  2. Alistair Holt on August 15, 2008 2:55 am

    Very nice. I can see this being very useful for calendar based apps and booking systems.

  3. Sammy Larbi on August 15, 2008 4:40 am

    Cool stuff - certainly something I could have used in previous calendar-type applications.

    One small bug (I think, anyway): In SmartMonth::Magic (I forget the class, but you know what I’m talking about) I noticed the line in method_missing that translates the first_monday (etc) is missing a “fourth”:

    self.send(func,raw) if %w(first second third last).include? func

    Some months have 5 of certain days of the week. For instance, this month, August 2008 has 5 Fridays, so I would have no way of getting the fourth.

    It’s not likely to come up, I wouldn’t think, but it is possible.

  4. Derek P. on August 15, 2008 10:01 am

    @Matt: I haven’t made it into a gem mostly because I am not really sure how to. Please feel free to help me out if you are interested!

    @Sammy: Thanks for the input! You are right, I need to add fourth. But actually, if you wanted to get the 5th week of August, you could do Month.august.last, that should return the last week of the month (which is sometimes the 4th, and other times the 5th). Thanks for the catching that bug!

  5. Eleo on August 20, 2008 10:28 am

    I agree, a gem would be more awesome.

  6. Derek P. on August 20, 2008 10:32 am

    @Eleo,

    I am not opposed to having it be a gem, I am just not familiar with the process. If you want to help convert it to a gem, I would be more than happy to make it part of the official plugin!

  7. Nome do Jogo » Blog Archive » Rails Podcast Brasil - Episódio 29 on August 25, 2008 10:39 pm

    [...] My First Ruby/Rails Contribution: SmartMonth [...]

  8. Panoctagon Open Source: SmartMonth | Panoctagon Blog on September 18, 2008 9:31 am

    [...] what sort of things you can do with the plugin? Take a look at my original post to see the [...]