FlexDate

Flexible dates for Ruby, as a gem. Originally written by Alex Reisner, packaged as a gem. github.com/alexreisner/flex_date

The Problem

You are collecting dates of historic events but you don’t always have exact dates. For example, you might know that an event occurred in March of 1862 but you don’t know the exact day. You could store this as a Ruby Date object that looks like ‘1862-03-01’ but, really, you don’t want to specify a day at all. You want to explicitly not store the day part of the date.

The Solution

FlexDate addresses this problem by extending Ruby’s included Date class. At the moment the following methods are provided to create partial dates:

FlexDate.new(year = nil, month = nil, date = nil)
year=(int)
month=(int)
day=(int)

Where a full date (year, month, and day) is specified, a FlexDate behaves exactly like a normal Ruby Date. When a partial date is specified, only the following methods will work:

year
month
day
to_s
strftime

Comparison operators also (== and <=>) work and I hope to have date arithmetic operators (+ and -) up and running soon.

Date parsing

FlexDate also comes with the method ‘parse` where it will currently create a FlexDate object from a date string that is formatted in the following way:

month day year or month/day/year or month-day-year month year or month/year or month-year year

The month can be January, Feb, or 3 The day must be an integer representing a day of the month The year must be a 4 digit number representing a year

Installation

To install FlexDate using Bundler, add it to your Gemfile.

gem 'flex_date', '0.1.0'

Integration with Rails/ActiveRecord

This will be packaged in a different gem called ‘flex_date_rails’

Code Discussion

You might expect FlexDate to be a subclass of Date, but this is not the case. That implementation would be far more complicated because the instance methods of Date require certain instance variables to be set, and to meet certain requirements for validity. Massaging the Date class to accept an invalid date seems like the wrong approach for the modest goals of FlexDate, which is simply to allow storing of partial dates, and duplicate the behavior of the Date class when a date is complete.

So instead, FlexDate is a very simple class that inherits from nothing, provides some (hopefully) useful methods for partial dates, and uses method_missing to fall back to Date when a FlexDate object is complete (specifies year, month, and day).

Any comments or suggestions regarding this design are welcome.

To-do List

  • Make date arithmetic work (Date minus FlexDate works, but neither FlexDate minus Date or FlexDate minus FlexDate works).

released under the MIT license.