Skip to content

Instantly share code, notes, and snippets.

@Dishwasha
Created May 1, 2013 16:46
Show Gist options
  • Save Dishwasha/5496492 to your computer and use it in GitHub Desktop.
Save Dishwasha/5496492 to your computer and use it in GitHub Desktop.
Date Helper
module DateHelper
DATE_MATCHER = /\A([01]?\d):(\d{2})\s(AM|PM)\z/
def date_add_minutes(formatted_date, minutes_to_add)
unless (formatted_date =~ DATE_MATCHER) == 0
raise ArgumentError, "Date must be formatted as [H]H:MM {AM|PM}"
end
unless minutes_to_add.is_a?(Integer)
raise ArgumentError, "Minutes must be an integer value"
end
hours, minutes, meridian = split_date(formatted_date)
unless hours > 0 && hours < 13
raise ArgumentError, "Hour must be between 1 and 12"
end
if minutes > 59
raise ArgumentError, "Minutes must be between 00 and 59"
end
if meridian == "PM"
hours += 12
end
minutes += minutes_to_add
hours += minutes / 60
minutes = minutes % 60
meridian = ['AM', 'PM'][hours / 12 % 2]
hours = hours % 12
return "#{'O' if hours < 12 && formatted_date[0] == '0'}#{hours}:#{"0" if minutes < 12}#{minutes} #{meridian}"
end
def split_date(formatted_date)
hours, minutes, meridian = formatted_date.match(DATE_MATCHER).to_a[1..-1]
return [Integer(hours[0] == '0' && hours.length == 2 ? hours[1] : hours), Integer(minutes[0] == "0" && minutes.length == 2 ? minutes[1] : minutes), meridian]
end
end
require 'date_helper'
include DateHelper
describe "date helper" do
describe "adding minutes" do
describe "input validation" do
describe "should receive a correctly formatted date" do
it "with hours less than 12 without zero padding" do
lambda{date_add_minutes("9:13 AM", 10)}.should_not raise_error
end
it "with hours less than 12 with zero padding" do
lambda{date_add_minutes("09:13 AM", 10)}.should_not raise_error
end
it "with 12 hours" do
lambda{date_add_minutes("12:13 AM", 10)}.should_not raise_error
end
end
describe "should raise error with an incorrectly formatted date" do
it "with garbage" do
lambda{date_add_minutes("abcd", 10)}.should raise_error(ArgumentError, 'Date must be formatted as [H]H:MM {AM|PM}')
end
it "with zero hours" do
lambda{date_add_minutes("00:13 AM", 10)}.should raise_error(ArgumentError, 'Hour must be between 1 and 12')
lambda{date_add_minutes("0:13 AM", 10)}.should raise_error(ArgumentError, 'Hour must be between 1 and 12')
end
it "with hours greater than 12" do
lambda{date_add_minutes("13:13 AM", 10)}.should raise_error(ArgumentError, 'Hour must be between 1 and 12')
end
end
describe "should receive a number of minutes" do
it "that is a positive integer" do
lambda{date_add_minutes("9:13 AM", 10)}.should_not raise_error
end
it "that is a negative integer" do
lambda{date_add_minutes("9:13 AM", -10)}.should_not raise_error
end
end
describe "should return a correctly formatted date" do
it "with zero padding"
it "without zero padding"
it "should return no padding when 12 more more hours"
end
end
describe "should return date" do
it "should add zero minutes" do
date_add_minutes("9:13 AM", 0).should == "9:13 AM"
end
describe "without rolling over meridian" do
it "should add minutes without exceeding 60 minutes" do
date_add_minutes("9:13 AM", 59 - 13).should == "9:59 AM"
end
it "should add minutes while exceeding 60 minutes" do
date_add_minutes("9:13 AM", 60 - 13).should == "10:00 AM"
end
end
describe "which rolls over meridian" do
it "should add minutes while exceeding 60 minutes"
end
end
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment