Last active
January 12, 2018 22:31
-
-
Save henrik/a8ba47c9b8ae4529cff4 to your computer and use it in GitHub Desktop.
Ruby Month class.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
require "attr_extras" # gem | |
class Month | |
vattr_initialize :year, :month_number | |
def self.from(object) | |
case object | |
when Month then object | |
else new(object.year, object.month) | |
end | |
end | |
# Relies on Rails' Time.zone. | |
def self.now | |
from(Time.zone.now) | |
end | |
def first_date | |
Date.new(year, month_number, 1) | |
end | |
def last_date | |
Date.new(year, month_number, -1) | |
end | |
def last_day | |
last_date.day | |
end | |
def date_for_day(number) | |
Date.new(year, month_number, number) | |
end | |
def previous | |
self.class.from(first_date - 1) | |
end | |
def next | |
self.class.from(last_date + 1) | |
end | |
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
require "spec_helper" | |
describe Month do | |
it "has value object equality" do | |
expect(Month.new(2014, 6)).to eq Month.new(2014, 6) | |
end | |
end | |
describe Month, ".from" do | |
it "builds a Month from a Date" do | |
month = Month.from(Date.new(2014, 6, 1)) | |
expect(month).to eq Month.new(2014, 6) | |
end | |
it "builds a Month from a Time" do | |
month = Month.from(Time.zone.local(2014, 6, 1, 0, 0, 0)) | |
expect(month).to eq Month.new(2014, 6) | |
end | |
it "returns the input when given a Month, since it's a value object" do | |
month = Month.from(Month.new(2014, 6)) | |
expect(month).to eq Month.new(2014, 6) | |
end | |
end | |
describe Month, ".now" do | |
it "is the current month" do | |
Timecop.freeze(Time.zone.local(2014, 1, 1, 0, 0, 0)) do | |
expect(Month.now).to eq Month.new(2014, 1) | |
end | |
end | |
end | |
describe Month, "#first_date" do | |
it "is the first date of the month" do | |
month = Month.new(2014, 2) | |
expect(month.first_date).to eq Date.new(2014, 2, 1) | |
end | |
end | |
describe Month, "#last_date" do | |
it "is the last date of the month" do | |
month = Month.new(2014, 2) | |
expect(month.last_date).to eq Date.new(2014, 2, 28) | |
end | |
end | |
describe Month, "#last_day" do | |
it "is the last day number of the month" do | |
month = Month.new(2014, 2) | |
expect(month.last_day).to eq 28 | |
end | |
end | |
describe Month, "#date_for_day" do | |
it "gives you such a date" do | |
date = Month.new(2014, 1).date_for_day(2) | |
expect(date).to eq Date.new(2014, 1, 2) | |
end | |
end | |
describe Month, "#previous" do | |
it "is the previous month" do | |
month = Month.new(2014, 2) | |
expect(month.previous).to eq Month.new(2014, 1) | |
expect(month.previous.previous).to eq Month.new(2013, 12) | |
end | |
end | |
describe Month, "#next" do | |
it "is the next month" do | |
month = Month.new(2013, 11) | |
expect(month.next).to eq Month.new(2013, 12) | |
expect(month.next.next).to eq Month.new(2014, 1) | |
end | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
If you use
pred
andsucc
rather thanprevious
andnext
you'll get range support for free...