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
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
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
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