class date has
function this(year, month, day) do
this.@set(year, month, day)
end
function @set(year, month, day) do
if month > 12 do
year += (month - 1) / 12
month = (month - 1) % 12 + 1
end
while day > (ndays = this.@ndaysofmonth(year, month)) do
day -= ndays; month += 1
if month > 12 do
month -= 12; year += 1
end
end
while day < 1 do
month += 1
if month < 1 do
month += 12; year -= 1
end
day += this.@ndaysofmonth(year, month)
end
this.@year, this.@month, this.@day = year, month, day
end
function @ndaysofmonth(year, month) do
if month == 2 then
if year % 4 == 0 and (year % 100 != 0 or year % 400 == 0) then
29 # leap year
else
28 # non-leap year
end
elif month in [4, 6, 9, 11] then
30
else
31
end
end
function .year do this.@year end
function .month do this.@month end
function .day do this.@day end
function operator +=(rhs) do
this.@set(this.@year, this.@month, this.@day + rhs)
return this
end
function operator -=(rhs) do
this.@set(this.@year, this.@month, this.@day - rhs)
return this
end
function operator +(rhs) do
tmp = this.clone()
return (tmp += rhs)
end
function operator -(rhs) do
tmp = this.clone()
return (tmp -= rhs)
end
function tostring do
"%04d-%02d-%02d" % [this.@year, this.@month, this.@day]
end
end