Skip to content

Commit

Permalink
first verison with date periods and calculation of some relative dates
Browse files Browse the repository at this point in the history
  • Loading branch information
robertino committed Jul 9, 2013
0 parents commit 50f8fe8
Show file tree
Hide file tree
Showing 12 changed files with 229 additions and 0 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
*.db
4 changes: 4 additions & 0 deletions Gemfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
source 'https://rubygems.org'

# Specify your gem's dependencies in disclosure-client.gemspec
gemspec
11 changes: 11 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
# Datebox

Provides help with managing dates and periods

## Usage

Include gem in Gemfile

gem 'datebox', :git => 'git@github.com:forward3d/datebox'

Take a look at examples in tests
1 change: 1 addition & 0 deletions Rakefile
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
require "bundler/gem_tasks"
23 changes: 23 additions & 0 deletions datebox.gemspec
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
# -*- encoding: utf-8 -*-
lib = File.expand_path('../lib', __FILE__)
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
# require 'f3d-cli/version'
require 'datebox'

Gem::Specification.new do |gem|
gem.name = "datebox"
gem.version = Datebox::VERSION
gem.authors = ["Robert Borkowski"]
gem.email = ["robert.borkowski@forward3d.com"]
gem.description = %q{Offers help with managing dates and periods}
gem.summary = %q{Got fed up with implementing date related functionality everywhere}
gem.homepage = "https://github.com/forward3d/datebox"

gem.files = `git ls-files`.split($/)
gem.executables = [] #gem.files.grep(%r{^bin/}).map{ |f| File.basename(f) }
gem.test_files = [] #gem.files.grep(%r{^(test|spec|features)/})
# gem.test_files = `git grep test`.split(/\n/).map {|f| File.basename(f.split(':').first)}
gem.require_paths = ["lib"]

# gem.add_dependency 'disclosure-client', :git => 'git@github.com:forward/disclosure-client-ruby.git'
end
7 changes: 7 additions & 0 deletions lib/datebox.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
require 'date'
require_relative 'datebox/period'
require_relative 'datebox/relative'
require_relative 'datebox/version'

module Datebox
end
51 changes: 51 additions & 0 deletions lib/datebox/period.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
module Datebox
class Period
attr_reader :from, :to

def initialize(from, to)
@from = from.is_a?(Date) ? from : Date.parse(from)
@to = to.is_a?(Date) ? to : Date.parse(to)
raise "FROM date should not be later than TO date" if @to < @from
end

def dates
(@from..@to).to_a
end

def ==(other)
@from == other.from && @to == other.to
end

class << self
def split_dates(start_date, end_date, period, options = {})
return (start_date..end_date).to_a if period == "day"
return split_weekly_dates(start_date, end_date, options) if period == "week"
return split_monthly_dates(start_date, end_date) if period == "month"
end

def split_weekly_dates(start_date, end_date, options = {})
last_weekday = options[:last_weekday] || "Sunday"
end_dates = []
end_of_week = (end_date.downto end_date - 6).to_a.find { |d| d.strftime("%A") == last_weekday }
while end_of_week - 6 >= start_date
end_dates << end_of_week
end_of_week -= 7
end
end_dates.sort
end

def split_monthly_dates(start_date, end_date)
end_dates = []
beginning_of_month = ::Date.parse("#{end_date.year}-#{end_date.month}-01").next_month
end_of_month = (beginning_of_month - 1 == end_date) ? end_date : beginning_of_month.prev_month - 1
while beginning_of_month.prev_month >= start_date
end_dates << end_of_month
beginning_of_month = ::Date.parse("#{end_of_month.year}-#{end_of_month.month}-01")
end_of_month = beginning_of_month - 1
end
end_dates.sort
end
end

end
end
79 changes: 79 additions & 0 deletions lib/datebox/relative.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
module Datebox
class Relative

@period = nil
@period_proc = nil

def to(relative_to)
relative_to = (relative_to.is_a?(Date) ? relative_to : Date.parse(relative_to))
@period_proc.call relative_to
end

def same_day
@period_proc = Proc.new {|relative_to| Period.new(relative_to, relative_to) }
self
end

def last_week(last_weekday = "Sunday")
@period_proc = Proc.new do |relative_to|
end_date = (relative_to.downto relative_to - 6).to_a.find { |d| d.strftime("%A") == last_weekday }
Period.new(end_date - 6, end_date)
end
self
end

def last_weekdays_between(start_day, end_day)
@period_proc = Proc.new do |relative_to|
end_date = (relative_to.downto relative_to - 6).to_a.find { |d| d.strftime("%A") == end_day }
start_date = (end_date - 7 .. end_date).to_a.find { |d| d.strftime("%A") == start_day }
Period.new(start_date, end_date)
end
self
end

def last_weeks_weekdays_as!(*days) #this one returns array!
@period_proc = Proc.new do |relative_to|
days.map do |p|
(relative_to.downto relative_to - 6).to_a.find { |d| d.strftime("%A") == p }
end
end
self
end

def last_month
@period_proc = Proc.new do |relative_to|
previous_month_start = Date.parse("#{relative_to.prev_month.strftime('%Y-%m')}-01")
previous_month_end = previous_month_start.next_month - 1
Period.new(previous_month_start, previous_month_end)
end
self
end

def month_to_date
@period_proc = Proc.new do |relative_to|
month_start = Date.parse("#{relative_to.strftime('%Y-%m')}-01")
Period.new(month_start, relative_to)
end
self
end

def last_year
@period_proc = Proc.new do |relative_to|
previous_year_start = Date.parse("#{relative_to.prev_year.year}-01-01")
previous_year_end = previous_year_start.next_year - 1
Period.new(previous_year_start, previous_year_end)
end
self
end

def year_to_date
@period_proc = Proc.new do |relative_to|
year_start = Date.parse("#{relative_to.year}-01-01")
Period.new(year_start, relative_to)
end
self
end

end

end
3 changes: 3 additions & 0 deletions lib/datebox/version.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
module Datebox
VERSION = "0.0.1"
end
5 changes: 5 additions & 0 deletions test/test_helper.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
require "test/unit"

root = File.join(File.dirname(File.expand_path(__FILE__)), '..')
require "#{root}/lib/datebox"

21 changes: 21 additions & 0 deletions test/unit/test_period.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
require '../test_helper'

class TestPeriod < Test::Unit::TestCase

def test_splits_periods_correctly
#day
assert_equal [Date.today - 1], Datebox::Period.split_dates(Date.today - 1, Date.today - 1, "day")
assert_equal [Date.today - 3, Date.today - 2, Date.today - 1], Datebox::Period.split_dates(Date.today - 3, Date.today - 1, "day")
#week
assert_equal [], Datebox::Period.split_dates(Date.parse("2013-06-15"), Date.parse("2013-06-22"), "week") #sat to sat
assert_equal [Date.parse("2013-06-23")], Datebox::Period.split_dates(Date.parse("2013-06-14"), Date.parse("2013-06-27"), "week") #fri to thu
assert_equal [Date.parse("2013-06-23")], Datebox::Period.split_dates(Date.parse("2013-06-17"), Date.parse("2013-06-23"), "week") #mon to sun
assert_equal [Date.parse("2013-06-16"), Date.parse("2013-06-23")], Datebox::Period.split_dates(Date.parse("2013-06-10"), Date.parse("2013-06-27"), "week") #mon to thu
#month
assert_equal [], Datebox::Period.split_dates(Date.parse("2013-01-02"), Date.parse("2013-01-31"), "month")
assert_equal [Date.parse("2013-01-31")], Datebox::Period.split_dates(Date.parse("2013-01-01"), Date.parse("2013-01-31"), "month")
assert_equal [Date.parse("2013-01-31")], Datebox::Period.split_dates(Date.parse("2012-12-02"), Date.parse("2013-02-02"), "month")
assert_equal [Date.parse("2013-01-31"), Date.parse("2013-02-28")], Datebox::Period.split_dates(Date.parse("2012-12-10"), Date.parse("2013-03-03"), "month")
end

end
23 changes: 23 additions & 0 deletions test/unit/test_relative.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
require '../test_helper'

class TestRelative < Test::Unit::TestCase

def test_calculates_correctly
# day
assert_equal [Date.parse('2013-07-07')], Datebox::Relative.new.same_day.to('2013-07-07').dates
# week
assert_equal Datebox::Period.new('2013-07-01', '2013-07-07'), Datebox::Relative.new.last_week.to('2013-07-09') #tue
assert_equal Datebox::Period.new('2013-07-01', '2013-07-05'), Datebox::Relative.new.last_weekdays_between("Monday", "Friday").to('2013-07-09') #tue
assert_equal Datebox::Period.new('2013-07-08', '2013-07-09'), Datebox::Relative.new.last_weekdays_between("Monday", "Tuesday").to('2013-07-09') #tue
# month
assert_equal Datebox::Period.new('2013-06-01', '2013-06-30'), Datebox::Relative.new.last_month.to('2013-07-09')
assert_equal Datebox::Period.new('2013-07-01', '2013-07-09'), Datebox::Relative.new.month_to_date.to('2013-07-09')
# year
assert_equal Datebox::Period.new('2012-01-01', '2012-12-31'), Datebox::Relative.new.last_year.to('2013-07-09')
assert_equal Datebox::Period.new('2013-01-01', '2013-07-09'), Datebox::Relative.new.year_to_date.to('2013-07-09')

# the one that's different
assert_equal [Date.parse('2013-07-01'), Date.parse('2013-07-03')], Datebox::Relative.new.last_weeks_weekdays_as!("Monday", "Wednesday").to('2013-07-05') #fri
end

end

0 comments on commit 50f8fe8

Please sign in to comment.