class DateTime

def change(options)

DateTime.new(2012, 8, 29, 22, 35, 0).change(year: 1981, hour: 0) # => DateTime.new(1981, 8, 29, 0, 0, 0)
DateTime.new(2012, 8, 29, 22, 35, 0).change(year: 1981, day: 1) # => DateTime.new(1981, 8, 1, 22, 35, 0)
DateTime.new(2012, 8, 29, 22, 35, 0).change(day: 1) # => DateTime.new(2012, 8, 1, 22, 35, 0)

:min, :sec, :offset, :start.
keys: :year, :month, :day, :hour,
then sec is set to 0. The +options+ parameter takes a hash with any of these
passed, then minute and sec is set to 0. If the hour and minute is passed,
:min, :sec) reset cascadingly, so if only the hour is
according to the +options+ parameter. The time options (:hour,
Returns a new DateTime where one or more of the elements have been changed
def change(options)
  ::DateTime.civil(
    options.fetch(:year, year),
    options.fetch(:month, month),
    options.fetch(:day, day),
    options.fetch(:hour, hour),
    options.fetch(:min, options[:hour] ? 0 : min),
    options.fetch(:sec, (options[:hour] || options[:min]) ? 0 : sec + sec_fraction),
    options.fetch(:offset, offset),
    options.fetch(:start, start)
  )
end