Time::Span and Time::MonthSpan

In Postgres, INTERVAL is stored as:

struct
  @months: Int32
  @days: Int32
  @microseconds: Int64
end

And here is the result:

SELECT DATE('2018-01-28') + INTERVAL '1 day 1 month';

-- 2018-03-01 00:00:00

SELECT DATE('2018-01-28') + INTERVAL '1 month 1 day';
-- 2018-03-01 00:00:00

Quite coherent :slight_smile:

in ActiveSupport however, things start to get really confusing:

irb(main):012:0> DateTime.parse("2018-01-28") + (1.day + 1.month)
=> Wed, 28 Feb 2018 00:00:00 +0000
irb(main):011:0> DateTime.parse("2018-01-28") + (1.month + 1.day)
=> Thu, 01 Mar 2018 00:00:00 +0000

:thinking:

In crystal:

puts Time.new(2018,1,28) + 1.month + 1.day
# > 2018-03-01 00:00:00 +07:00
puts Time.new(2018,1,28) + 1.day + 1.month
# > 2018-02-28 00:00:00 +07:00

Like active record :thinking:

puts Time.new(2018,1,28) + (1.day + 1.month)

# Error in XXXX: no overload matches 'Time::Span#+' with type Time::MonthSpan
# Overloads are:
# - Time::Span#+(other : self)
# - Time::Span#+()

I honestly 100% prefer the PostgreSQL version of Interval, which sounds less error prone imho.

EDIT: Insolvable?

SELECT DATE('2018-01-28') + INTERVAL '1 day' + INTERVAL '1 month';
-- 2018-02-28 00:00:00