extracted CalendarHelper to it's own file

diff --git a/lib/modules/calendar/calendar.rb b/lib/modules/calendar/calendar.rb
index 0ffae3e..c5d8558 100644
--- a/lib/modules/calendar/calendar.rb
+++ b/lib/modules/calendar/calendar.rb
@@ -1,6 +1,6 @@
 require 'date'
 require 'modules/persistent/persistent'
-
+require 'modules/calendar/calendar_helper'
 module RST

   # Calendar-module provides the Calendar-class which is supposed to hold
@@ -40,43 +40,7 @@ module RST
   #
   module Calendar

-    # Some helper-methods useful when dealing with dates
-    module CalendarHelper
-
-      # You can use 'today' or any format which Date.parse can handle.
-      # @param [nil|String|Time|Date] param
-      # @return [Date] always returns a Date regardless of the type of input
-      def ensure_date(param)
-        if param.is_a?(Date) || param.is_a?(::Time)
-          param
-        elsif param =~ /today/i || param.nil?
-          Date.today
-        elsif param =~ /\d+[a-zA-Z]/i
-          get_today_plus(param)
-        else
-          Date.parse(param)
-        end
-      end
-
-      # Get Today + param
-      # @param [String] param nDWM n=Number Day Weeks Months
-      def get_today_plus(param)
-        offset = 0
-        param.scan(/(\d+)([a-z])/i) do |count,unit|
-          offset = case unit[0].downcase
-          when 'd'
-            count.to_i.days
-          when 'w'
-            count.to_i.weeks
-          when 'm'
-            count.to_i.months
-          else
-            raise "Unknown unit #{unit}. Valid units are d,w,m or days,weeks,months"
-          end
-        end
-        Date.parse( (Time.now + offset).to_s )
-      end
-    end
+    include CalendarHelper

     # Calendar has a name and will be stored in Persistent::DiskStore(CALENDAR_FILE)
     # with it's name as the id. Thus you can save different calendars in
@@ -183,7 +147,7 @@ module RST
       # @return [String]|nil
       def to_text(from,to,empty=false,ids=false)
         unless (_content=list_days(from,to)).empty?
-          left_column=build_cal(ensure_date(from),ensure_date(to))
+          left_column=build_cal(parse_date_param(from),parse_date_param(to))
           right_column=("EVENTS:\n"+list_days(from,to,empty,ids).join("\n")).split(/\n/)
           render_2col_lines(left_column, right_column)
         end
@@ -264,13 +228,6 @@ module RST

       # @endgroup

-      # Convert strings to a date
-      # @param [Date|Time|String] param - default is 'today'
-      # @return [Date|Time]
-      def parse_date_param(param=Date.today)
-        ensure_date(param)
-      end
-
     end

   end
diff --git a/lib/modules/calendar/calendar_event.rb b/lib/modules/calendar/calendar_event.rb
index cef51c9..1d779b2 100644
--- a/lib/modules/calendar/calendar_event.rb
+++ b/lib/modules/calendar/calendar_event.rb
@@ -30,7 +30,7 @@ module RST
       def initialize(_date,_label)
         @label = _label
         @id ||= SecureRandom::hex(4)
-        schedule! ensure_date(_date)
+        schedule! parse_date_param(_date)
       end

       # override abstract method for an Eventable
diff --git a/lib/modules/calendar/calendar_helper.rb b/lib/modules/calendar/calendar_helper.rb
new file mode 100644
index 0000000..cfb3284
--- /dev/null
+++ b/lib/modules/calendar/calendar_helper.rb
@@ -0,0 +1,56 @@
+module RST
+
+  # Some useful helpers for dates
+  module CalendarHelper
+
+    # You can use 'today' or any format which Date.parse can handle.
+    # @example
+    #   parse_date_param('1w')
+    #   parse_date_param('-41d')
+    #   parse_date_param('1week')
+    #   parse_date_param('4months')
+    #   parse_date_param('-12m')
+    #   parse_date_param('today')
+    # @param [nil|String|Time|Date] param
+    # @return [Date] always returns a Date regardless of the type of input
+    def parse_date_param(param)
+      if param.is_a?(Date) || param.is_a?(::Time)
+        param
+      elsif param =~ /today/i || param.nil?
+        Date.today
+      elsif param =~ /\d+[a-zA-Z]/i
+        get_today_plus(param)
+      else
+        Date.parse(param)
+      end
+    end
+
+    private
+
+    # Get Today + param
+    # @example
+    #   get_today_plus('1w')
+    #   get_today_plus('-41d')
+    #   get_today_plus('1week')
+    #   get_today_plus('4months')
+    #   get_today_plus('-12m')
+    # @param [String] param nDWM n=Number Day Weeks Months
+    def get_today_plus(param)
+      offset = 0
+      param.scan(/(\-?)(\d+)([a-z])/i) do |dir,count,unit|
+        _count = count.to_i * ( dir.to_s == '-' ?  -1 : 1 )
+        offset = case unit[0].downcase
+                 when 'd'
+                   _count.to_i.days
+                 when 'w'
+                   _count.to_i.weeks
+                 when 'm'
+                   _count.to_i.months
+                 else
+                   raise "Unknown unit #{unit}. Valid units are d,w,m or days,weeks,months"
+                 end
+      end
+      Date.parse( (Time.now + offset).to_s )
+    end
+  end
+end
diff --git a/specs/modules/calendar/calendar_helper_spec.rb b/specs/modules/calendar/calendar_helper_spec.rb
new file mode 100644
index 0000000..9eda818
--- /dev/null
+++ b/specs/modules/calendar/calendar_helper_spec.rb
@@ -0,0 +1,36 @@
+require_relative '../../spec_helper'
+
+describe CalendarHelper do
+
+  include CalendarHelper
+
+  describe '.parse_date_param(string) should interpret' do
+    before do
+      @today = Date.today
+    end
+
+    it 'interprets [-]1d' do
+      parse_date_param('1d').to_s.should == (@today+1).to_s
+      parse_date_param('-1d').to_s.should == (@today-1).to_s
+    end
+
+    it 'interprets [-]1w' do
+      parse_date_param('1w').to_s.should == (@today+7).to_s
+      parse_date_param('-1w').to_s.should == (@today-7).to_s
+    end
+
+    it 'interprets [-]1m' do
+      parse_date_param('1m').month.should == (@today+31).month
+      parse_date_param('-1m').month.should == (@today-31).month
+    end
+
+    it 'interprets \'today\'' do
+      parse_date_param('today').should == Date.today
+    end
+
+    it 'should throws an ArgumentError if string can\'t be parsed' do
+      expect { parse_date_param('dummy') }.to raise_error ArgumentError
+    end
+  end
+end
+
diff --git a/specs/modules/calendar/calendar_spec.rb b/specs/modules/calendar/calendar_spec.rb
index fee94b5..dfd6de2 100644
--- a/specs/modules/calendar/calendar_spec.rb
+++ b/specs/modules/calendar/calendar_spec.rb
@@ -16,24 +16,6 @@ describe 'Calendar module:' do
       calendar.end_date.year.should == 2013
     end

-    it '.span should return number of days between start and end' do
-      calendar = Calendar::Calendar.new('dob','31. 8. 1964', '2014-08-31')
-      (calendar.span/1.year).round.should == 50
-    end
-
-    it '.list_days(from,to,true) should list week days' do
-      calendar = Calendar::Calendar.new('dob','31. 8. 1964', '1964-09-02')
-      calendar.list_days('31.8.1964','1964-09-02',true).join("\n").should =~ /Mon, Aug 31 1964/
-      calendar.list_days('31.8.1964','1964-09-02',true).join("\n").should =~ /Tue, Sep 01 1964/
-      calendar.list_days('31.8.1964','1964-09-02',true).join("\n").should =~ /Wed, Sep 02 1964/
-    end
-
-    it '.list_days(from,to,true) should display lines with entries if empty==true (bugfix)' do
-      calendar = Calendar::Calendar.new('dob','31. 8. 1964', '1964-09-02')
-      calendar << Calendar::CalendarEvent.new('31.8.1964', 'Andi Altendorfer')
-      calendar.list_days('31.8.1964','1964-09-02',true).join("\n").should =~ /Mon, Aug 31 1964: Andi Altendorfer/
-    end
-
     it '.new(name,string,string) should interpret today as argument' do
       calendar = Calendar::Calendar.new('dob','1.1.1970', 'today')
       calendar.end_date.should == Date.today
@@ -54,6 +36,24 @@ describe 'Calendar module:' do
       expect { Calendar::CalendarEvent.new('1x','dummy') }.to raise_error RuntimeError
     end

+    it '.span should return number of days between start and end' do
+      calendar = Calendar::Calendar.new('dob','31. 8. 1964', '2014-08-31')
+      (calendar.span/1.year).round.should == 50
+    end
+
+    it '.list_days(from,to,true) should list week days' do
+      calendar = Calendar::Calendar.new('dob','31. 8. 1964', '1964-09-02')
+      calendar.list_days('31.8.1964','1964-09-02',true).join("\n").should =~ /Mon, Aug 31 1964/
+      calendar.list_days('31.8.1964','1964-09-02',true).join("\n").should =~ /Tue, Sep 01 1964/
+      calendar.list_days('31.8.1964','1964-09-02',true).join("\n").should =~ /Wed, Sep 02 1964/
+    end
+
+    it '.list_days(from,to,true) should display lines with entries if empty==true (bugfix)' do
+      calendar = Calendar::Calendar.new('dob','31. 8. 1964', '1964-09-02')
+      calendar << Calendar::CalendarEvent.new('31.8.1964', 'Andi Altendorfer')
+      calendar.list_days('31.8.1964','1964-09-02',true).join("\n").should =~ /Mon, Aug 31 1964: Andi Altendorfer/
+    end
+
     it '.form=, .to=, setter method for :from, and :to should be defined' do
       cal = Calendar::Calendar.new('dob','1.1.1970', '2.1.1970')
       cal.start_date.year.should == 1970
Added -no option to --print-calendar (to overwrite saved defaults)