floraison / fugit

time tools (cron, parsing, durations, ...) for Ruby, rufus-scheduler, and flor
MIT License
353 stars 29 forks source link

time computation with monthly duration like "P-2M" is incorrect #83

Closed mreinsch closed 1 year ago

mreinsch commented 1 year ago

Issue description

Using a duration with negative months causes times to be miscalculated.

How to reproduce

some Ruby code to illustrate the issue:

require 'fugit'

puts (Fugit::Duration.parse('P-2M') + Time.parse('2021-01-01T00:00:00Z')).to_utc_time
# 2021-01-01 00:00:00 UTC  # incorrect, should be 2020-10-01 00:00:00 UTC

puts (Fugit::Duration.parse('P-2M') + Time.parse('2021-02-01T00:00:00Z')).to_utc_time
# gems/et-orbi-1.2.7/lib/et-orbi/make.rb:111:in `utc': mon out of range (ArgumentError)  # should be 2020-11-01 00:00:00 UTC

puts (Fugit::Duration.parse('P-72d') + Time.parse('2021-01-01T00:00:00Z')).to_utc_time
# 2020-10-21 00:00:00 UTC  # correct

puts (Fugit::Duration.parse('P2M') + Time.parse('2021-12-01T00:00:00Z')).to_utc_time
# 2022-02-01 00:00:00 UTC  # correct

Or else, please describe carefully what to do to see a live example of the issue.

Error and error backtrace (if any)

see above example

Expected behaviour

see above example

Context

Darwin elu.local 22.2.0 Darwin Kernel Version 22.2.0: Fri Nov 11 02:08:47 PST 2022; root:xnu-8792.61.2~4/RELEASE_X86_64 x86_64
ruby 3.0.4p208 (2022-04-12 revision 3fa771dded) [x86_64-darwin21]
[:env_tz, nil]
(secs:1674123846.3943,utc~:"2023-01-19 10:24:06.3942999839782715",ltz~:"CET")
(etz:nil,tnz:"CET",tziv:"2.0.5",tzidv:nil,rv:"3.0.4",rp:"x86_64-darwin21",win:false,rorv:nil,astz:nil,eov:"1.2.7",eotnz:#<TZInfo::TimezoneProxy: Africa/Ceuta>,eotnfz:"+0100",eotlzn:"Africa/Ceuta",eotnfZ:"CET",debian:nil,centos:nil,osx:"zoneinfo/Europe/Berlin")
[:fugit, "1.8.0"]
[:now, 2023-01-19 11:24:08.652599 +0100, :zone, "CET"]

Additional context