floraison / fugit

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

previous_time and next_time produce strange results when combining actual dates with day of week #64

Closed donkeybridge closed 2 years ago

donkeybridge commented 2 years ago

Issue description

I started to search for the next occurence of Feb 29th during weekend, what resulted in Sat, 2021-02-05. Further experiments showed a some gap in interpreting cron strings.

How to reproduce

2.7.5 :001 > require 'fugit'
2.7.5 :002 > conf.echo = true
 => true
2.7.5 :003 > Fugit::VERSION
 => "1.5.2"
2.7.5 :004 > Fugit::Cron.parse('0 0 29 2 0,6').next_time.strftime('%a, %Y-%m-%d')
 => "Sat, 2022-02-05"
2.7.5 :005 > Fugit::Cron.parse('0 0 29 2 *').next_time.strftime('%a, %Y-%m-%d')  # THIS IS CORRECT
 => "Thu, 2024-02-29"
2.7.5 :006 > Fugit::Cron.parse('0 0 29 2 0-7').next_time.strftime('%a, %Y-%m-%d')
 => "Tue, 2022-02-01"
2.7.5 :007 > Fugit::Cron.parse('0 0 29 2 *').previous_time.strftime('%a, %Y-%m-%d') # THIS IS CORRECT
 => "Sat, 2020-02-29"
2.7.5 :008 > Fugit::Cron.parse('0 0 29 2 0-7').previous_time.strftime('%a, %Y-%m-%d')
 => "Sun, 2021-02-28"

At first I was guessing this related to leap day, but unfortunately it got worse:

2.7.5 :009 > Fugit::Cron.parse('0 0 11 11 *').next_time.strftime('%a, %Y-%m-%d')  # THIS IS CORRECT
 => "Fri, 2022-11-11"
2.7.5 :010 > Fugit::Cron.parse('0 0 11 11 0-7').next_time.strftime('%a, %Y-%m-%d')
 => "Tue, 2022-11-01"
2.7.5 :011 > Fugit::Cron.parse('0 0 11 11 3-6').next_time.strftime('%a, %Y-%m-%d')
 => "Wed, 2022-11-02"
2.7.5 :012 > Fugit::Cron.parse('0 0 11 11-12 3-6').next_time.strftime('%a, %Y-%m-%d')
 => "Wed, 2021-12-29"
2.7.5 :013 > Fugit::Cron.parse('0 0 11 11-12 3-6').next_time.strftime('%a, %Y-%m-%d')
 => "Wed, 2021-12-29"
2.7.5 :014 > Fugit::Cron.parse('0 0 11-13 11 3-6').next_time.strftime('%a, %Y-%m-%d')
 => "Wed, 2022-11-02"
2.7.5 :015 > Fugit::Cron.parse('0 0 11 * 3-6').next_time.strftime('%a, %Y-%m-%d')   # SIC!
 => "Wed, 2021-12-29"

Error and error backtrace (if any)

Expected behaviour


2.7.5 :003 > Fugit::Cron.parse('0 0 29 2 0,6').next_time.strftime('%a, %Y-%m-%d')
 => "Sun, 2032-02-29"
2.7.5 :004 > Fugit::Cron.parse('0 0 11-13 11 3-6').next_time.strftime('%a, %Y-%m-%d')
 => "Fri, 2022-11-11"
2.7.5 :005 > Fugit::Cron.parse('0 0 7-10 11 3-6').next_time.strftime('%a, %Y-%m-%d')
 => "Wed, 2022-11-08"
2.7.5 :006 > Fugit::Cron.parse('0 0 11 * 3-6').next_time.strftime('%a, %Y-%m-%d')
 => "Fri, 2022-02-11"

Context

Please replace the content of this section with the output of the following commands:

$ uname -a
Linux servername.domainname.tld 4.19.0-17-amd64 #1 SMP Debian 4.19.194-1 (2021-06-10) x86_64 GNU/Linux
$ bundle exec ruby -v
ruby 2.7.5p203 (2021-11-24 revision f69aeb8314) [x86_64-linux]
$ bundle exec ruby -e "p [ :env_tz, ENV['TZ'] ]"
[:env_tz, nil]
$ bundle exec ruby -r et-orbi -e "EtOrbi._make_info"
(secs:1640553552.822941,utc~:"2021-12-26 21:19:12.8229410648345947",ltz~:"UTC")
(etz:nil,tnz:"UTC",tziv:"2.0.4",tzidv:nil,rv:"2.7.5",rp:"x86_64-linux",win:false,rorv:nil,astz:nil,eov:"1.2.6",eotnz:#<TZInfo::DataTimezone: Etc/UTC>,eotnfz:"+0000",eotlzn:"Etc/UTC",eotnfZ:"UTC",debian:"Etc/UTC",centos:nil,osx:"Etc/UTC")
$ bundle exec ruby -r fugit -e "p [ :fugit, Fugit::VERSION" ]
-e:1: syntax error, unexpected end-of-input, expecting ']'
$ bundle exec ruby -r fugit -e "p [ :fugit, Fugit::VERSION ]"
[:fugit, "1.5.2"]
$ bundle exec ruby -e "p [ :now, Time.now, :zone, Time.now.zone ]"
[:now, 2021-12-26 21:19:23.916665874 +0000, :zone, "UTC"]

Additional context

jmettraux commented 2 years ago

From man 5 crontab:

     Note: The day of a command's execution can be specified by two fields —
     day-of-month and day-of-week.  If both fields are restricted (i.e. aren't
     *), the command will be run when either field matches the current time.
     For example,

           30 4 1,15 * 5

     would cause a command to be run at 4:30 am on the 1st and 15th of each
     month, plus every Friday.

As seen in gh-5 and gh-35.

See also https://crontab.guru/#0_0_29_2_0,6

Not closing yet, I want to investigate

Fugit::Cron.parse('0 0 11 * 3-6').next_time.strftime('%a, %Y-%m-%d')   # SIC!
  # => "Wed, 2021-12-29"
jmettraux commented 2 years ago
Fugit::Cron.parse('0 0 11 * 3-6').next_time.strftime('%a, %Y-%m-%d')   # SIC!
  # => "Wed, 2021-12-29"

Same. https://crontab.guru/#0_0_11_*_3-6

I wish you a happy new year!

jmettraux commented 1 year ago

ref gh-78