Giter VIP home page Giter VIP logo

fugit's People

Contributors

amatsuda avatar chukwuemekaajah avatar cristianbica avatar delbetu avatar dependabot[bot] avatar gitter-badger avatar grosser avatar hlascelles avatar jmettraux avatar mreinsch avatar olleolleolle avatar petergoldstein avatar solteszad avatar vivekmiyani avatar wishdev avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar

fugit's Issues

Problem parsing 'every 12 hours at minute 50'

Issue description

Fugit::Nat.parse('every 12 hours at minute 50').to_cron_s returns "50 * * * *" when it should return "50 0,12 * * *". The hours are getting ignored.

How to reproduce

require 'fugit'
Fugit::Nat.parse('every 12 hours at minute 50').to_cron_s

#=> "50 * * * *"

Expected behaviour

require 'fugit'
Fugit::Nat.parse('every 12 hours at minute 50').to_cron_s

#=> "50 0,12 * * *" (or "50 */12 * * *")

Context

Darwin Jeromes-2017-MBP.local 19.6.0 Darwin Kernel Version 19.6.0: Sun Jul  5 00:43:10 PDT 2020; root:xnu-6153.141.1~9/RELEASE_X86_64 x86_64
ruby 2.7.1p83 (2020-03-31 revision a0c7c23c9c) [x86_64-darwin19]
(secs:1596594797.9150012,utc~:"2020-08-05 02:33:17.9150011539459229",ltz~:"PDT")
(etz:nil,tnz:"PDT",tziv:"2.0.2",tzidv:nil,rv:"2.7.1",rp:"x86_64-darwin19",win:false,rorv:nil,astz:nil,eov:"1.2.4",eotnz:#<TZInfo::TimezoneProxy: America/Ensenada>,eotnfz:"-0700",eotlzn:"America/Ensenada",eotnfZ:"PDT",debian:nil,centos:nil,osx:"zoneinfo/America/Los_Angeles")

Incorrect transition into DST for America/New_York

As pointed at by @harsha-flipp in jmettraux/rufus-scheduler#329

Given the script

#require 'rufus-scheduler'
require 'fugit'

# https://www.timeanddate.com/time/zone/usa/chicago
# https://www.timeanddate.com/time/change/usa/chicago

# https://www.timeanddate.com/time/zone/usa/newyork
# https://www.timeanddate.com/time/change/usa/newyork

#ENV['TZ'] = 'America/Chicago' # so that Time#to_s below stays in Chicago
ENV['TZ'] = 'America/New_York' # so that Time#to_s below stays in New York

c = Fugit.parse_cron('5 0 * * *')
#c = Fugit.parse_cron('30 4 * * *')


p [ :tz, ENV['TZ'] ]
p [ :ruby, RUBY_VERSION, RUBY_PLATFORM ]
p [ :tzinfo, TZInfo::VERSION ]
p [ :fugit, Fugit::VERSION ]

# into daylight saving time

puts

t = Time.parse('2021-03-10')
10.times do
  t = c.next_time(t)
  p t.to_s
end

# out of daylight saving time

puts

t = Time.parse('2021-11-05')
10.times do
  t = c.next_time(t)
  p t.to_s
end

America/Chicago yields the result below, which correctly goes into DST and out of it.

[:tz, "America/Chicago"]
[:ruby, "2.7.1", "x86_64-openbsd6.7"]
[:tzinfo, "2.0.4"]
[:fugit, "1.5.2"]

"2021-03-10 00:05:00 -0600"
"2021-03-11 00:05:00 -0600"
"2021-03-12 00:05:00 -0600"
"2021-03-13 00:05:00 -0600"
"2021-03-14 00:05:00 -0600"
"2021-03-15 00:05:00 -0500"
"2021-03-16 00:05:00 -0500"
"2021-03-17 00:05:00 -0500"
"2021-03-18 00:05:00 -0500"
"2021-03-19 00:05:00 -0500"

"2021-11-05 00:05:00 -0500"
"2021-11-06 00:05:00 -0500"
"2021-11-07 00:05:00 -0500"
"2021-11-08 00:05:00 -0600"
"2021-11-09 00:05:00 -0600"
"2021-11-10 00:05:00 -0600"
"2021-11-11 00:05:00 -0600"
"2021-11-12 00:05:00 -0600"
"2021-11-13 00:05:00 -0600"
"2021-11-14 00:05:00 -0600"

But for America/New_York

[:tz, "America/New_York"]
[:ruby, "2.7.1", "x86_64-openbsd6.7"]
[:tzinfo, "2.0.4"]
[:fugit, "1.5.2"]

"2021-03-10 00:05:00 -0500"
"2021-03-11 00:05:00 -0500"
"2021-03-12 00:05:00 -0500"
"2021-03-13 00:05:00 -0500"
"2021-03-14 00:05:00 -0500"
"2021-03-14 23:05:00 -0500" # the change happens but the TZ is still the same?
"2021-03-15 23:05:00 -0500"
"2021-03-16 23:05:00 -0500"
"2021-03-17 23:05:00 -0500"
"2021-03-18 23:05:00 -0500"

"2021-11-05 00:05:00 -0400"
"2021-11-06 00:05:00 -0400"
"2021-11-07 00:05:00 -0400"
"2021-11-08 00:05:00 -0500"
"2021-11-09 00:05:00 -0500"
"2021-11-10 00:05:00 -0500"
"2021-11-11 00:05:00 -0500"
"2021-11-12 00:05:00 -0500"
"2021-11-13 00:05:00 -0500"
"2021-11-14 00:05:00 -0500"

Also have to try with "30 4 * * *" as OP did.

"at 12:00 PM" gives the wrong crontab pattern

Issue description

When I parse the string "at 12:00 PM", the result is "0 24 * * *" which is wrong

How to reproduce

require 'fugit'
c = Fugit.parse('at 12:00 PM')
p c.original # "0 24 * * *"

Expected behaviour

It should return "0 12 * * *"

Context

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

Darwin Khaleds-MBP 20.5.0 Darwin Kernel Version 20.5.0: Sat May  8 05:10:33 PDT 2021; root:xnu-7195.121.3~9/RELEASE_X86_64 x86_64
ruby 2.7.1p83 (2020-03-31 revision a0c7c23c9c) [x86_64-darwin20]
[:env_tz, nil]
(secs:1623078834.395216,utc~:"2021-06-07 15:13:54.3952159881591797",ltz~:"EEST")
(etz:nil,tnz:"EEST",tziv:"1.2.9",tzidv:nil,rv:"2.7.1",rp:"x86_64-darwin20",win:false,rorv:nil,astz:nil,eov:"1.2.4",eotnz:#<TZInfo::TimezoneProxy: Asia/Amman>,eotnfz:"+0300",eotlzn:"Asia/Amman",eotnfZ:"EEST",debian:nil,centos:nil,osx:"zoneinfo/Asia/Amman")
"1.4.4"

Parse::Nat with 24h times doesn't parse correctly

# Parses correctly with am/pm times
puts Fugit.parse_nat('every day at 6pm and 8pm UTC').hours.inspect
=> [18, 20]

# Parses incorrectly with 24h times
puts Fugit.parse_nat('every day at 18:00 and 20:00 UTC').hours.inspect
=> [20]

Running Fugit 1.2.2 / Ruby 2.6.3 / Ubuntu 18.04

Natural parsing for ranges of hours in ranges of days

Issue description

Hello there, I'm wondering if fugit supports natural parsing of both days and weeks? We're looking for a way to define blocks of time where people are or aren't available. Below is a simple example.

How to reproduce

require 'fugit'

f = Fugit::Nat.parse('every weekday 8am to 5pm') # => nil

Expected behaviour

I was expecting to get a fugit cron object back that looks a little something like this?

#<Fugit::Cron:0x000055f7859a1ca8 @original="* 8-17 * * 1-5", @cron_s=nil, @seconds=[0], @minutes=[0..59], @hours=[8..17], @monthdays=nil, @months=nil, @weekdays=[[1], [2], [3], [4], [5]], @zone=nil, @timezone=nil>

It might not be feasible to include every minute of every hour in the 8am-5pm range, but any help getting a string like this to parse would be very helpful. Many thanks for this gem, it truly is wonderful.

Context

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

Linux a716f734f0ee 4.19.76-linuxkit #1 SMP Tue May 26 11:42:35 UTC 2020 x86_64 GNU/Linux

ruby 2.6.6p146 (2020-03-31 revision 67876) [x86_64-linux]

[:env_tz, nil]

(secs:1601231894.3672342,utc~:"2020-09-27 18:38:14.3672342300415039",ltz~:"UTC")
(etz:nil,tnz:"UTC",tziv:"1.2.7",tzidv:nil,rv:"2.6.6",rp:"x86_64-linux",win:false,rorv:"6.0.3.3",astz:[ActiveSupport::TimeZone, "Etc/UTC"],eov:"1.2.4",eotnz:#<TZInfo::DataTimezone: Etc/UTC>,eotnfz:"+0000",eotlzn:"Etc/UTC",eotnfZ:"UTC",debian:"Etc/UTC",centos:nil,osx:"Etc/UTC")

Additional context

It turns out that parsing every monday to friday 8am and 5pm will correctly parse the day range supplied, but change the hours from a list; 8am and 5pm to a range; 8am to 5pm returns a nil.

I tried with multi: true and still get a nil returned.

NoMethodError when parse'ing empty string

Issue description

Parsing an empty string leads to NoMethodError instead of ArgumentError (when using do_parse) or nil (when using parse).

How to reproduce

require 'fugit'
Fugit::Cron.parse(' ')
 => nil 
Fugit::Cron.parse(nil)
 => nil 
Fugit::Cron.parse('')
Traceback (most recent call last):
        1: from (irb):20
NoMethodError (undefined method `subgather' for nil:NilClass)

Expected behaviour

Empty string should parse as invalid cron string, just like " " or nil.

Context

Linux 242fdceb1492 5.4.39-linuxkit #1 SMP Fri May 8 23:03:06 UTC 2020 x86_64 x86_64 x86_64 GNU/Linux
ruby 2.6.6p146 (2020-03-31 revision 67876) [x86_64-linux]
[:env_tz, nil]
(secs:1606866124.7550213,utc~:"2020-12-01 23:42:04.755021333694458",ltz~:"UTC")
(etz:nil,tnz:"UTC",tziv:"1.2.8",tzidv:nil,rv:"2.6.6",rp:"x86_64-linux",win:false,rorv:nil,astz:nil,eov:"1.2.4",eotnz:#<TZInfo::TimezoneProxy: Etc/UCT>,eotnfz:"+0000",eotlzn:"Etc/UCT",eotnfZ:"UTC",debian:"/UTC",centos:nil,osx:"/UTC")
"1.4.1"

Additional context

I'm using Fugit in Rails context.

TZInfo::PeriodNotFound exception when using Time.zone

Issue description

When using Time.zone instead of ENV['TZ'], Cron#next_time throws a TZInfo::PeriodNotFound exception.

How to reproduce

require 'fugit'
require 'active_support/core_ext/time/zones'
Time.zone = 'America/Santiago'  # it works with ENV['TZ'] = 'America/Santiago'
t = EtOrbi::EoTime.parse('2021-08-18 01:00:00')
puts Fugit::Cron.parse('0 8 15 * *').next_time(t).to_s

Error and error backtrace (if any)

 11: from /Users/pascal/.rvm/gems/ruby-2.7.2/gems/fugit-1.5.1/lib/fugit/cron.rb:251:in `next_time'
 10: from /Users/pascal/.rvm/gems/ruby-2.7.2/gems/fugit-1.5.1/lib/fugit/cron.rb:251:in `loop'
  9: from /Users/pascal/.rvm/gems/ruby-2.7.2/gems/fugit-1.5.1/lib/fugit/cron.rb:261:in `block in next_time'
  8: from /Users/pascal/.rvm/gems/ruby-2.7.2/gems/fugit-1.5.1/lib/fugit/cron.rb:107:in `inc_day'
  7: from /Users/pascal/.rvm/gems/ruby-2.7.2/gems/et-orbi-1.2.4/lib/et-orbi/make.rb:59:in `make_time'
  6: from /Users/pascal/.rvm/gems/ruby-2.7.2/gems/et-orbi-1.2.4/lib/et-orbi/make.rb:108:in `make_from_array'
  5: from /Users/pascal/.rvm/gems/ruby-2.7.2/gems/et-orbi-1.2.4/lib/et-orbi/make.rb:44:in `parse'
  4: from /Users/pascal/.rvm/gems/ruby-2.7.2/gems/tzinfo-2.0.3/lib/tzinfo/timezone.rb:648:in `local_to_utc'
  3: from /Users/pascal/.rvm/gems/ruby-2.7.2/gems/tzinfo-2.0.3/lib/tzinfo/timestamp.rb:142:in `for'
  2: from /Users/pascal/.rvm/gems/ruby-2.7.2/gems/tzinfo-2.0.3/lib/tzinfo/timezone.rb:652:in `block in local_to_utc'
  1: from /Users/pascal/.rvm/gems/ruby-2.7.2/gems/tzinfo-2.0.3/lib/tzinfo/timezone.rb:500:in `period_for_local'
     TZInfo::PeriodNotFound (2021-09-05 00:00:00 is an invalid local time.)

Expected behaviour

The timezone setting in Time.zone should be used as fallback when ENV['TZ'] is nil and the correct output ("2021-09-15 08:00:00 -0300") should be returned.

Context

Darwin Pascals-BigPro.fritz.box 20.6.0 Darwin Kernel Version 20.6.0: Wed Jun 23 00:26:31 PDT 2021; root:xnu-7195.141.2~5/RELEASE_X86_64 x86_64
ruby 2.7.2p137 (2020-10-01 revision 5445e04352) [x86_64-darwin20]
[:env_tz, nil]
(secs:1631862880.412856,utc~:"2021-09-17 07:14:40.4128561019897461",ltz~:"CEST")
(etz:nil,tnz:"CEST",tziv:"2.0.4",tzidv:nil,rv:"2.7.2",rp:"x86_64-darwin20",win:false,rorv:nil,astz:nil,eov:"1.2.4",eotnz:#<TZInfo::TimezoneProxy: Africa/Ceuta>,eotnfz:"+0200",eotlzn:"Africa/Ceuta",eotnfZ:"CEST",debian:nil,centos:nil,osx:"zoneinfo/Europe/Zurich")
"1.5.1"
[:now, 2021-09-17 09:15:13.611169 +0200, :zone, "CEST"]

)

Natural cron "every 15th of the month"

Issue description

Trying to convert natural language to a cron expression that happens every specific day of the month.

Looking at the specs, I see that it was intended, but currently not working?

#'every 1st of the month at midnight' => '',

Is it planned?

I don't even mind if it will be a little less natural language, like:

  • every month on day 2 at 10:00
  • every month on days 1,15 at 10:00 # twice a month 1st and 15th

if that makes it easier to implement.

How to reproduce

require 'fugit'
p Fugit::Nat.parse('Every 2nd of the month at 10:00')   #=> nil

Strange behaviour with DST?

Issue description

First of all, I'm based in Switzerland. Our clock will change next week to summer time. We use Fugit in a project to allow users schedule background jobs. We have a test suite that has a test where a job should run each week with the instruction every monday at midnight. We compare the result of Fugit with an expected value to make sure our scheduler works.

Now, instructing Fugit to give the next date for said schedule strangely gives a date in two weeks instead of next week. Other hours seem to work fine:

irb(main):003:0> Fugit.parse("every monday at 3am").next_time.to_s
=> "2021-03-29 03:00:00 +0200"
irb(main):004:0> Fugit.parse("every monday at 2am").next_time.to_s
=> "2021-03-29 02:00:00 +0200"
irb(main):005:0> Fugit.parse("every monday at 1am").next_time.to_s
=> "2021-03-29 01:00:00 +0200"
irb(main):006:0> Fugit.parse("every monday at midnight").next_time.to_s
=> "2021-04-05 00:00:00 +0200"

I'm not sure if it is related to DST and if this is supposed to happen (I don't know cron too well).

How to reproduce

See above.

Error and error backtrace (if any)

Not needed, as no error will be printed.

Expected behaviour

next_time should print Mon, 29 Mar 2021 00:00:00 CEST +02:00.

Context

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

uname -a
bundle exec ruby -v
bundle exec ruby -e "p [ :env_tz, ENV['TZ'] ]"
bundle exec ruby -r et-orbi -e "EtOrbi._make_info"
bundle exec ruby -r fugit -e "p Fugit::VERSION"

(It's supposed to look like

Linux apf-work-home 5.4.0-67-generic #75-Ubuntu SMP Fri Feb 19 18:03:38 UTC 2021 x86_64 x86_64 x86_64 GNU/Linux
ruby 2.5.8p224 (2020-03-31 revision 67882) [x86_64-linux]
[:env_tz, nil]
(secs:1616405592.3763082,utc~:"2021-03-22 09:33:12.3763082027435303",ltz~:"CET")
(etz:nil,tnz:"CET",tziv:"1.2.9",tzidv:nil,rv:"2.5.8",rp:"x86_64-linux",win:false,rorv:nil,astz:nil,eov:"1.2.4",eotnz:#<TZInfo::DataTimezone: Europe/Zurich>,eotnfz:"+0100",eotlzn:"Europe/Zurich",eotnfZ:"CET",debian:"Europe/Zurich",centos:nil,osx:"Europe/Zurich")
"1.4.2"

)

Feature request: parse_nat weekday ranges

Would be handy to have weekday ranges, e.g. instead of:
every Mon,Tue,Wed,Thu,Fri at 18:00, have the option to write
every Mon-Fri at 18:00 or
every Mon to Fri at 18:00.

UTC cron next_time should be a UTC time, not a local time

require 'fugit'

#ENV['TZ'] = 'Asia/Shanghai'
#ENV['TZ'] = 'CST'

EtOrbi._make_info

puts "---"

p Time.now
p Time.now.utc
cron = Fugit.do_parse_cron('0 0 1 1 *')
p cron
p cron.next_time.to_s
p cron.next_time.utc.to_s

puts "---"

p Time.now
p Time.now.utc
cron = Fugit.do_parse_cron('0 0 1 1 * UTC')
p cron
p cron.next_time.to_s
p cron.next_time.utc.to_s
(secs:1546413051.166213,utc~:"2019-01-02 07:10:51.1662130355834961",ltz~:"JST")
(etz:nil,tnz:"JST",tzid:nil,rv:"2.3.7",rp:"x86_64-darwin17",
  win:false,rorv:nil,astz:nil,eov:"1.1.6",eotnz:#<TZInfo::TimezoneProxy: Asia/Tokyo>,
  eotnfz:"+0900",eotlzn:"Asia/Tokyo",debian:nil,centos:nil,osx:"zoneinfo/Asia/Tokyo")
---
2019-01-02 16:10:51 +0900
2019-01-02 07:10:51 UTC
#<Fugit::Cron:0x00007f97d51fb750 @original="0 0 1 1 *", @cron_s=nil,
  @seconds=[0], @minutes=[0], @hours=[0], @monthdays=[1], @months=[1], @weekdays=nil,
  @zone=nil, @timezone=nil>
"2020-01-01 00:00:00 +0900"
"2019-12-31 15:00:00 UTC"
---
2019-01-02 16:10:51 +0900
2019-01-02 07:10:51 UTC
#<Fugit::Cron:0x00007f97d3c665e8 @original="0 0 1 1 * UTC", @cron_s=nil,
  @seconds=[0], @minutes=[0], @hours=[0], @monthdays=[1], @months=[1], @weekdays=nil,
  @zone="UTC", @timezone=#<TZInfo::DataTimezone: UTC>>
"2020-01-01 00:00:00 +0900"
"2019-12-31 15:00:00 UTC"

The second p cron.next_time.to_s should be in the UTC timezone.

As seen in gh-11.

cron time + DST trouble

I'm using Fugit.parse('55 6 * * 2#1 America/Los_Angeles') for a monthly alert.
This has been alerting fine at 6:55 all the time, but 2020-12-01 it alerted 1 hour early (5:55).
Last time it alerted Nov 3 at 6:55 AM which was in DST already, so I'd have expected that to fail and not the December one, but there is a chance it was scheduled before DST kicked in.
I reproduced the issue using Timecop.travel('2020-11-30') and Fugit.parse('55 6 * * 2#1 America/Los_Angeles').next_time.to_debug_s and it looks like the timezone is wrong:

Timecop.travel('2020-11-30')
# => 2020-11-30 00:00:00 -0800
Fugit.parse('55 6 * * 2#1 America/Los_Angeles').next_time.to_s
# => "2020-12-01 07:55:00 -0700" <-- wrong ?
Time.now
# => 2020-11-30 00:09:15 -0800

[feature request] cron syntax validation

Issue description

It would be great to have a method like .validate that can validate and check if the syntax of the cron string is correct.

How to reproduce

N/A

Expected behaviour

N/A

Context

I want to store the cron string into the database and use it later for checking purposes.
So it would be great if I can do some validation with the string before saving it.

Additional context

N/A

Every x minute is parsed incorrectly for cron

image

*/55 * * * * should run once every 55 minutes, but fugit runs it at x:55 and x:00, where x is 0-23. In the example above, it's ran at 12:00, 12:55, 13:00, 13:55, etc. when it should run at 12:00, 12:55, 13:50, 14:45, etc.

Handling timezones in cron lines

Is the handling of timezones in fugit cron lines planned? (ie, will rufus-scheduler 4.x be compatible with rufus-scheduler 3.x?).

Background: que-scheduler uses fugit to parse cron lines. It was hoped the config file it would mirror the one for resque-scheduler. However fugit doesn't seem to handle timezones. This means the config for que-scheduler throws errors.

I could move to using rufus-scheduler 3.x in que-scheduler for now, but didn't want to add features which would not be forwardly compatible.

Problem parsing 'every day at 8:30'

Issue description

  • Fugit::Nat.parse('every day at 8:30')&.to_cron_s returns nil when I think it should return "30 8 * * *".

    It works with 'every day at 08:30' but not when there is no leading 0.

  • Fugit::Nat.parse('every day at 8:30 pm')&.to_cron_s returns nil when it should return "30 20 * * *".

    Here the problem is that even if you provide a leading zero with 'every day at 08:30 pm', it does not work when there is am or pm.

How to reproduce

require 'fugit'

Fugit::Nat.parse('every day at 8:30')&.to_cron_s
#=> nil

Fugit::Nat.parse('every day at 8:30 pm')&.to_cron_s
#=> nil

Fugit::Nat.parse('every day at 08:30 pm')&.to_cron_s
#=> nil

Expected behaviour

require 'fugit'

Fugit::Nat.parse('every day at 8:30')&.to_cron_s
#=> "30 8 * * *"

Fugit::Nat.parse('every day at 8:30 pm')&.to_cron_s
#=> "30 20 * * *"

Fugit::Nat.parse('every day at 08:30 pm')&.to_cron_s
#=> "30 20 * * *"

Context

Darwin Jeromes-2017-MBP.local 19.6.0 Darwin Kernel Version 19.6.0: Sun Jul  5 00:43:10 PDT 2020; root:xnu-6153.141.1~9/RELEASE_X86_64 x86_64
ruby 2.7.1p83 (2020-03-31 revision a0c7c23c9c) [x86_64-darwin19]
(secs:1596594797.9150012,utc~:"2020-08-05 02:33:17.9150011539459229",ltz~:"PDT")
(etz:nil,tnz:"PDT",tziv:"2.0.2",tzidv:nil,rv:"2.7.1",rp:"x86_64-darwin19",win:false,rorv:nil,astz:nil,eov:"1.2.4",eotnz:#<TZInfo::TimezoneProxy: America/Ensenada>,eotnfz:"-0700",eotlzn:"America/Ensenada",eotnfZ:"PDT",debian:nil,centos:nil,osx:"zoneinfo/America/Los_Angeles")

Support for timezone offsets

Do you plan to support timezone offsets in the future?
Currently, the following examples do not work:

Fugit::Cron.parse("29 9 16 * * UTC/+11")
Fugit::Cron.parse("29 9 16 * * Etc/GMT-11")

weekday cron does not run today when started before execution time

fugit 1.4.2

the second Tuesday of the week was today, we started the cron earlier today, but it never executed, because it thinks the next execution is next month and not today ... so seems like the weekday calculation needs to take time of day into account

TZ=utc bundle exec ruby -r bundler/setup -r fugit -e 'puts Time.now'
2021-02-09 17:41:10 +0000
TZ=utc bundle exec ruby -r bundler/setup -r fugit -e 'puts Fugit.do_parse_cron("55 18 * * 2#1").next_time.to_s'
2021-03-02 18:55:00 +0000
  it "calculates weekdays correctly when starting at the same day" do
    Time.stubs(:now).returns(Time.parse("2021-02-02 00:00:00")) # tuesday morning
    Fugit.do_parse_cron("59 23 * * 1").next_time.to_s.must_equal "2021-02-02 23:59:00 -0000"
  end

endless loop dealing with cron "seconds" string

@conet hijacked the closed issue gh-11, challenging the fix there, but provided nothing that supports his accusation.

In fact, there is a source issue report at:
https://gitlab.com/gitlab-org/gitlab-ce/issues/59273

we had:

gitlab_rails['ldap_sync_worker_cron'] = "5 * * * * *"
gitlab_rails['ldap_group_sync_worker_cron'] = "10 * * * * *"

instead of:

gitlab_rails['ldap_sync_worker_cron'] = "5 * * * *"
gitlab_rails['ldap_group_sync_worker_cron'] = "10 * * * *"

Once the cron expression is fixed cpu usage goes back to normal

OP adds:

invalid cron expressions should not cause such behavior.

irb(main):001:0> require 'Fugit'
=> true
irb(main):002:0> Fugit.parse('5 * * * * *')
=> #<Fugit::Cron:0x00007f91ba8d54c0
  @original="5 * * * * *", @cron_s=nil, @seconds=[5],
  @minutes=nil, @hours=nil, @monthdays=nil, @months=nil, @weekdays=nil,
  @zone=nil, @timezone=nil>
irb(main):003:0> Fugit.parse('10 * * * * *')
=> #<Fugit::Cron:0x00007f91ba844650 @original="10 * * * * *", @cron_s=nil, @seconds=[10],
  @minutes=nil, @hours=nil, @monthdays=nil, @months=nil, @weekdays=nil,
  @zone=nil, @timezone=nil>

In other words: "5 * * * * *" means "every time the second hand hits the 5".

Sidekiq-cron allows for second crons (see sidekiq-cron/sidekiq-cron#240). These are NOT invalid cron expressions.

Questions to @conet :

  • you mention
2019-03-20_18:36:54.79856 2019-03-20T18:36:54.798Z 2977 TID-ot8g7o9m9 WARN: Thread TID-ot89u8ea9 scheduler
2019-03-20_18:36:54.79857 2019-03-20T18:36:54.798Z 2977 TID-ot8g7o9m9 WARN: /opt/gitlab/embedded/lib/ruby/gems/2.5.0/gems/tzinfo-1.2.5/lib/tzinfo/time_or_datetime.rb:321:in `wrap'
...

as an endless loop. Do you mean that this warn trace repeats endlessly in your log?

  • Does the LDAP sync work your settings seem to imply happen or not? Does the LDAP sync work happens every 5 / 10 seconds ? Does it happen but with a different schedule ? Or is it NOT happening at all?

Thanks in advance and best regards.

Incorrect #rough_frequency and #brute_frequency for '0 */5 * * *'

Issue description

Parsing of the above cron schedule can't seem to be parsed properly:

Rufus::Scheduler.parse('0 */5 * * *').rough_frequency
=> 14400
# even if we try `brute_schedule` it's off:
Rufus::Scheduler.parse('0 */5 * * *').brute_frequency
=> #<Fugit::Cron::Frequency:0x0000000124f5f440 @delta_max=21600, @delta_min=14400, @occurrences=1822, @span=31482000.0, @span_years=0.9982876712328768, @yearly_occurrences=1825.1252144082332>

value should be: 18000

Parsing of 0 */3 * * *, 0 */4 * * * and 0 */6 * * * work fine it seems.

How to reproduce

See above

Expected behaviour

Seems like a simple cron schedule like this, should be able to be parsed properly? If neither of these methods work, what other way is there to get an accurate frequency?

Invalid “hours” in range cause cron #next_time loop breaker issue

Issue description

Values outside 0-23 in an hour range cause an infinite loop error.

How to reproduce

require 'fugit'
c = Fugit.parse('* 0-24 * * *')
RuntimeError (too many loops for {:min=>0, :max=>23, :sta=>0, :edn=>24, :sla=>1} #range, breaking, please fill an issue at https://git.io/fjJC9)

Expected behaviour

The “24” being out of range should either result in a parsing error or being treated as 0.

Context

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

Darwin Kinzie 18.7.0 Darwin Kernel Version 18.7.0: Thu Jun 20 18:42:21 PDT 2019; root:xnu-4903.270.47~4/RELEASE_X86_64 x86_64
ruby 2.6.2p47 (2019-03-13 revision 67232) [x86_64-darwin18]
(secs:1565722428.8614998,utc~:"2019-08-13 18:53:48.8614997863769531",ltz~:"PDT")
(etz:nil,tnz:"PDT",tziv:"1.2.5",tzidv:nil,rv:"2.6.2",rp:"x86_64-darwin18",win:false,rorv:nil,astz:nil,eov:"1.2.1",eotnz:#<TZInfo::TimezoneProxy: America/Dawson>,eotnfz:"-0700",eotlzn:"America/Dawson",eotnfZ:"PDT",debian:nil,centos:nil,osx:"zoneinfo/America/Vancouver")

Additional context

Encountered via in-the-wild user input!

Fugit::Cron previous_time method bug

Hi, there:

I was in +8 timezone, I exec the following statement in rails console:
Fugit::Cron.parse('0 16 30 9 *').previous_time.to_local_time

and I got the following error:
RuntimeError: too many loops for "0 16 30 9 *" #previous_time, breaking

Also, the same error occurred when I exec:
Fugit::Cron.parse('0 16 31 10 *').previous_time.to_local_time

I guess that when the cron is across the month, this error occurred. So boundary conditions need
to be fully considered

Fugit::Nat.parse('every hour') returns nil

Fugit::Nat.parse('every hour') returns nil
Fugit::Nat.parse('every day') incorrectly returns '0 * * * *' which is every hour
It would be great if it could handle some common cases without an explicit number.

require 'fugit'
['second', 'minute', 'hour', 'day', 'week', 'month', 'year'].each do |period|
  puts "every #{period}: #{Fugit::Nat.parse("every #{period}")&.to_cron_s}"
  puts "every 1 #{period}: #{Fugit::Nat.parse("every 1 #{period}")&.to_cron_s}"
end
every second: [MISSING]
every 1 second: * * * * * * [OK]
every minute: [MISSING]
every 1 minute: * * * * * [OK]
every hour: [MISSING]
every 1 hour: 0 * * * * [OK]
every day: 0 * * * * [INCORRECT]
every 1 day: 0 0 * * * [OK]
every week: [MISSING]
every 1 week: [MISSING]
every month: [MISSING]
every 1 month: 0 0 1 * * [OK]
every year: [MISSING]
every 1 year: [MISSING]

For every day/every week/every month/every year, it should mirror the behaviour of cron, i.e.

@yearly        Run once a year, "0 0 1 1 *".
@monthly       Run once a month, "0 0 1 * *".
@weekly        Run once a week, "0 0 * * 0".
@daily         Run once a day, "0 0 * * *".
@hourly        Run once an hour, "0 * * * *".

(above taken from man 5 crontab)

Thanks!

cron #next_time loop breaker issue

I know it's an invalid date and I'm happy in latest version it no longer hangs infinitely but your response did say report it.

So minimum reproduce case.

cron = Fugit::Cron.new("* * 31 11 *")
cron.next_time

RuntimeError: too many loops for "* * 31 11 *" #next_time, breaking, please fill an issue at https://git.io/fjJC9
from /Users/petera/.rvm/gems/ruby-2.2.10/gems/fugit-1.2.0/lib/fugit/cron.rb:225:in `block in next_time'

Question: how to find the end of the current cron "validity interval"?

Challenge description

I'm using the cron syntax not only as an indicator for several points in time but as a duration as well.
E.g. I interpret (and check via match?(Time.now)) the following as:
'10-40 22 * * mon-fri' indicates "every Monday till Friday between 22:10 and 22:40".
'* 0 * * mon' indicates "every Monday between 00:00 and 00:59".
'* 8 * * *' indicates "every day between 08:00 and 08:59".
...you get the idea. ;)

Works fine so far, but instead of finding the time when the next "interval" will start I need to find (if in an active interval) when it will end.
E.g. if current time was 2020-11-01 08:32:02, this interval
'* 8 * * *' should return a time of 2020-11-01 08:59:59 (or even 2020-11-01 09:00:00).

Do you think that's possible? Any ideas appreciated! :)

Fugit::Nat.parse with multi: :fail returns an array

When specifying multi: :fail, the expected behaviour is not to return an array

puts Fugit::Nat.parse('every 1 hour').inspect
#<Fugit::Cron:0x0000560b30bce300 @original="0 * * * *", @cron_s=nil, @seconds=[0], @minutes=[0], @hours=nil, @monthdays=nil, @months=nil, @weekdays=nil, @zone=nil, @timezone=nil>

puts Fugit::Nat.parse('every 1 hour', multi: :fail).inspect
[#<Fugit::Cron:0x0000560b30c028a8 @original="0 * * * *", @cron_s=nil, @seconds=[0], @minutes=[0], @hours=nil, @monthdays=nil, @months=nil, @weekdays=nil, @zone=nil, @timezone=nil>]

Thanks again for everything

Fugit::Nat.parse with different times in the same hour not parsed as single cron

# When there are different hours, it works correctly
Fugit::Nat.parse('every day at 18:00 and 19:00 UTC').original
=> "0 18,19 * * * UTC"

# When there are different minutes in the same hour, it doesn't
Fugit::Nat.parse('every day at 18:00 and 18:15 UTC').original
=> "0 18 * * * UTC" # should be: "0,15 18 * * * UTC"

# More complex example (but possibly difficult to implement)
Fugit::Nat.parse('every day at 18:00 and 18:15 and 19:00 and 19:15 UTC').original
=> "0 18 * * * UTC" # should be: "0,15 18,19 * * * UTC"

Thanks again

Timezone seems ignored in cron.match?

As originally reported by @assembler in floraison/et-orbi#21

require 'fugit'

cron = Fugit::Cron.parse("0 0 * * * PST8PDT")
p cron
  # => #<Fugit::Cron:0x00007fb3b8bdf880
  #      @original="0 0 * * * PST8PDT", @cron_s=nil, @seconds=[0],
  #      @minutes=[0], @hours=[0], @monthdays=nil, @months=nil, @weekdays=nil,
  #      @zone="PST8PDT", @timezone=#<TZInfo::DataTimezone: PST8PDT>>


#p cron.match?(Time.utc(2019, 1, 1, 0, 0, 0))
p cron.match?(EtOrbi.parse('2019-1-1'))
  # => true

#p cron.match?(Time.new(2019, 1, 1, 0, 0, 0, TZInfo::Timezone.get('UTC')))
p cron.match?(EtOrbi.parse('2019-1-1 UTC'))
  # => true

#p cron.match?(Time.new(2019, 1, 1, 0, 0, 0, TZInfo::Timezone.get('CET')))
p cron.match?(EtOrbi.parse('2019-1-1 ETC'))
  # => true

#p cron.match?(Time.new(2019, 1, 1, 0, 0, 0, TZInfo::Timezone.get('PST8PDT')))
p cron.match?(EtOrbi.parse('2019-1-1 PST8PDT'))
  # => true

parse_nat with weekday ranges doesn't parse correctly

# Parses correctly with days specified individually
puts Fugit.parse_nat('every Fri,Sat,Sun at 18:00 UTC').weekdays.inspect
=> [[0], [5], [6]]

# Parses incorrectly with day ranges spanning the end of week
puts Fugit.parse_nat('every Fri-Sun at 18:00 UTC').weekdays.inspect
=> [[0], [1], [2], [3], [4], [5]]

Invalid cron (zero day of month) results in unpredictable behaviour

Trying to create an invalid cron with a 0th day of month "works".

Fugit::Cron.parse('0 2 1 0 *')                                                                                                                                                                       
=> #<Fugit::Cron:0x00007f90279df648 @cron_s=nil, @hours=[2], @minutes=[0], @monthdays=[1], @months=[0], @original="0 2 1 0 *", @seconds=[0], @timezone=nil, @weekdays=nil, @zone=nil>

The resulting object is unusable (especially for next_time), but there was no error, and it did not return nil.

Should(n't) it do so?

Don't double cron matches when getting out of DST

Fugit::Cron does not handle the edge cases of daylight saving time.

Fugit::Cron.new("0 0 * * * America/New_York").brute_frequency shows 365 occurrences, which makes sense at one per day for a year. However, Fugit::Cron.new("1 1 * * * America/New_York").brute_frequency shows 366 occurrences (since 1:01 a.m. occurs twice when moving the clock backwards) and Fugit::Cron.new("1 2 * * * America/New_York").brute_frequency shows 364 occurrences (since 2:01 a.m. is skipped when moving the clock forward).

As I quickly researched around the internet, I see that this support is dependent on the version of cron used but I think this is a good feature to have. What are your thoughts on adding in this support?

Cron#rough_frequency returns 0 for some cronlines

Hi 👋 !

Issue description

Given cronlines that are supposed to run every x days, rough_frequency returns 0 in some cases while others work as expected (see the examples below).

How to reproduce

require 'fugit'
Fugit.parse('0 0 */2 * * Europe/Berlin').rough_frequency
# => 0
Fugit.parse('0 0 */2 * * Europe/Berlin').brute_frequency
# => #<Fugit::Cron::Frequency:0x00007ff5c5bc0da0 @delta_max=342000, @delta_min=86400, @occurrences=185, @span=31536000.0, @span_years=1.0, @yearly_occurrences=185.0>
[32] pry(main)> Fugit.parse('0 0 */1 * *').rough_frequency
=> 86400
[33] pry(main)> Fugit.parse('0 0 */2 * *').rough_frequency
=> 0
[34] pry(main)> Fugit.parse('0 0 */3 * *').rough_frequency
=> 0
[35] pry(main)> Fugit.parse('0 0 */4 * *').rough_frequency
=> 172800
[36] pry(main)> Fugit.parse('0 0 */5 * *').rough_frequency
=> 0
[37] pry(main)> Fugit.parse('0 0 */6 * *').rough_frequency
=> 0
[38] pry(main)> Fugit.parse('0 0 */7 * *').rough_frequency
=> 172800
[39] pry(main)> Fugit.parse('0 0 */8 * *').rough_frequency
=> 518400
[40] pry(main)> Fugit.parse('0 0 */9 * *').rough_frequency
=> 259200
[41] pry(main)> Fugit.parse('0 0 */10 * *').rough_frequency
=> 0
[42] pry(main)> Fugit.parse('0 0 */11 * *').rough_frequency
=> 691200
[43] pry(main)> Fugit.parse('0 0 */12 * *').rough_frequency
=> 518400
[44] pry(main)> Fugit.parse('0 0 */13 * *').rough_frequency
=> 345600
[45] pry(main)> Fugit.parse('0 0 */14 * *').rough_frequency
=> 172800
[46] pry(main)> Fugit.parse('0 0 */15 * *').rough_frequency
=> 0
[47] pry(main)> Fugit.parse('0 0 */16 * *').rough_frequency
=> 1209600
[48] pry(main)> Fugit.parse('0 0 */17 * *').rough_frequency
=> 1123200
[49] pry(main)> Fugit.parse('0 0 */18 * *').rough_frequency
=> 1036800
[50] pry(main)> Fugit.parse('0 0 */19 * *').rough_frequency
=> 950400
[51] pry(main)> Fugit.parse('0 0 */20 * *').rough_frequency
=> 864000
[52] pry(main)> Fugit.parse('0 0 */21 * *').rough_frequency
=> 777600
[53] pry(main)> Fugit.parse('0 0 */22 * *').rough_frequency
=> 691200
[54] pry(main)> Fugit.parse('0 0 */23 * *').rough_frequency
=> 604800
[55] pry(main)> Fugit.parse('0 0 */24 * *').rough_frequency
=> 518400
[56] pry(main)> Fugit.parse('0 0 */25 * *').rough_frequency
=> 432000
[57] pry(main)> Fugit.parse('0 0 */26 * *').rough_frequency
=> 345600
[58] pry(main)> Fugit.parse('0 0 */27 * *').rough_frequency
=> 259200
[59] pry(main)> Fugit.parse('0 0 */28 * *').rough_frequency
=> 172800
[60] pry(main)> Fugit.parse('0 0 */29 * *').rough_frequency
=> 86400
[61] pry(main)> Fugit.parse('0 0 */30 * *').rough_frequency
=> 0

Context

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

Darwin local 18.7.0 Darwin Kernel Version 18.7.0: Tue Aug 20 16:57:14 PDT 2019; root:xnu-4903.271.2~2/RELEASE_X86_64 x86_64
ruby 2.6.1p33 (2019-01-30 revision 66950) [x86_64-darwin18]
(secs:1586083793.553639,utc~:"2020-04-05 10:49:53.5536389350891113",ltz~:"CEST")
(etz:"Europe/Berlin",tnz:"CEST",tziv:"1.2.7",tzidv:nil,rv:"2.6.1",rp:"x86_64-darwin18",win:false,rorv:"6.0.2.2",astz:[ActiveSupport::TimeZone, "Europe/Berlin"],eov:"1.2.2",eotnz:#<TZInfo::DataTimezone: Europe/Berlin>,eotnfz:"+0200",eotlzn:"Europe/Berlin",eotnfZ:"CEST",debian:nil,centos:nil,osx:"zoneinfo/Europe/Berlin")

Skips four hour increment with UTC on some occasions

Issue description

Hi, thanks for making this library, it's been really useful.

We're running into an issue with this cron: 0 8-19/4 * * *.
We basically want it to run every day from 8am to 7pm with a 4-hour increment, which boils down to 8am, 12pm, and 4pm.

We're having issues when we set the timezone to America/New_York, but have the system time in UTC.
If we query for the next time at 8am, fugit yields 20:00 UTC (4pm EST) when we expect 16:00 UTC (12pm EST). It seems to skip a 4-hour block when requesting next right on the edge.

How to reproduce

Gemfile

source 'https://rubygems.org'

platforms :jruby do
  gem 'activesupport', '4.2.11.1'
  gem 'fugit', '1.3.6'
end

utc_repro.rb

require 'active_support/time'
require 'fugit'

cron = Fugit.parse('0 8-19/4 * * *')
# note that Time.parse only cares about sys tz, so this is 12:00 UTC <=> 08:00 EST
puts Time.use_zone('America/New_York') { cron.next_time(Time.parse('2020-09-11 12:00:00')).to_local_time }
  1. set computer timezone to UTC
  2. bundle install
  3. ruby utc_repro.rb

Error

Running ruby utc_repro.rb yields
2020-09-11 20:00:00 UTC
when we would expect
2020-09-11 16:00:00 UTC.

Context

We're using jruby 9.2.13.0, but MRI should yield the same results.

Lastly, if we update the time and add a few minutes (e.g. try 12:10 UTC), we get the expected time:
puts Time.use_zone('America/New_York') { cron.next_time(Time.parse('2020-09-11 12:10:00')).to_local_time }
yields
2020-09-11 16:00:00 UTC.

Feel free to let me know if anything is unclear, happy to clarify.

too many loops in #next_time/previous_time for invalid dates

Issue description

This is again a known issue reporting as per error message. Although the input date is incorrect (e.g. Feb 31st) the :parse method returns a valid object and the loop :next_time reaches the max number of iterations.

How to reproduce

require 'fugit'
c = Fugit.parse('0 12 31 2 *')
p c.next_time

Same issue occurs with all inputs that have month within 1-12 and day within 1-31 but are not valid dates:

  • Feb 30th
  • Feb 31st
  • Apr 31st
  • Jun 31st
  • Sep 31st
  • Nov 31st

Suggestions

  • Could the parse method return nil directly when invalid combination of month-day is detected?

cron #next_time loop breaker issue

Issue description

A clear and concise description of what the issue is. (There is an example of a carefully filled issue at #18)

How to reproduce

The simplest piece of code that reproduces the issue, for example:

require 'fugit'
c = Fugit.parse('0 9 29 feb *')
p c.previous_time

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

Error and error backtrace (if any)

(This should look like:

ArgumentError: found no time information in "0-65 * * * *"
  from /home/john/w/fugit/lib/fugit/parse.rb:32:in `do_parse'
  from ...
  from /home/john/.gem/ruby/2.3.7/gems/bundler-1.16.2/lib/bundler/vendor/thor/lib/thor/base.rb:466:in `start'
  from /home/john/.gem/ruby/2.3.7/gems/bundler-1.16.2/lib/bundler/cli.rb:18:in `start'
  from /home/john/.gem/ruby/2.3.7/gems/bundler-1.16.2/exe/bundle:30:in `block in <top (required)>'
  from /home/john/.gem/ruby/2.3.7/gems/bundler-1.16.2/lib/bundler/friendly_errors.rb:124:in `with_friendly_errors'
  from /home/john/.gem/ruby/2.3.7/gems/bundler-1.16.2/exe/bundle:22:in `<top (required)>'
  from /home/john/.gem/ruby/2.3.7/bin/bundle:22:in `load'
  from /home/john/.gem/ruby/2.3.7/bin/bundle:22:in `<main>'

)

Expected behaviour

A clear and concise description of what you expected to happen.

Context

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

uname -a
bundle exec ruby -v
bundle exec ruby -e "p [ :env_tz, ENV['TZ'] ]"
bundle exec ruby -r et-orbi -e "EtOrbi._make_info"
bundle exec ruby -r fugit -e "p Fugit::VERSION"
bundle exec ruby -e "p [ :now, Time.now, :zone, Time.now.zone ]

(It's supposed to look like

Darwin pollux.local 17.7.0 Darwin Kernel Version 17.7.0: Thu Dec 20 21:47:19 PST 2018;
  root:xnu-4570.71.22~1/RELEASE_X86_64 x86_64
ruby 2.3.7p456 (2018-03-28 revision 63024) [x86_64-darwin17]
[:env_tz, nil]
(secs:1553304485.185308,utc~:"2019-03-23 01:28:05.18530797958374023",ltz~:"JST")
(etz:nil,tnz:"JST",tziv:"2.0.0",tzidv:"1.2018.9",rv:"2.3.7",rp:"x86_64-darwin17",win:false,
  rorv:nil,astz:nil,eov:"1.1.7",eotnz:#<TZInfo::TimezoneProxy: Asia/Tokyo>,eotnfz:"+0900",
  eotlzn:"Asia/Tokyo",eotnfZ:"JST",debian:nil,centos:nil,osx:"zoneinfo/Asia/Tokyo")
"1.3.9"

)

Additional context

Add any other context about the problem here.

cron #next_time loop breaker issue

Issue description

A clear and concise description of what the issue is. (There is an example of a carefully filled issue at #18)

How to reproduce

The simplest piece of code that reproduces the issue, for example:

heroku local

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

Error and error backtrace (if any)

(This should look like:

/home/ggallardo/.rvm/gems/ruby-3.0.2/bin/sidekiq:23:in `load'
10:04:01 AM worker.1 |  /home/ggallardo/.rvm/gems/ruby-3.0.2/bin/sidekiq:23:in `<main>'
10:04:01 AM worker.1 |  /home/ggallardo/.rvm/gems/ruby-3.0.2/bin/ruby_executable_hooks:22:in `eval'
10:04:01 AM worker.1 |  /home/ggallardo/.rvm/gems/ruby-3.0.2/bin/ruby_executable_hooks:22:in `<main>'
10:04:01 AM worker.1 |  2021-08-17T14:04:01.193Z pid=11350 tid=b42 WARN: RuntimeError: too many loops for "0 8 15 * *" #next_time, breaking, cron expression most likely invalid (Feb 30th like?), please fill an issue at https://git.io/fjJC9
10:04:01 AM worker.1 |  2021-08-17T14:04:01.193Z pid=11350 tid=b42 WARN: /home/ggallardo/.rvm/gems/ruby-3.0.2/gems/fugit-1.5.0/lib/fugit/cron.rb:238:in `block in next_time'
10:04:01 AM worker.1 |  /home/ggallardo/.rvm/gems/ruby-3.0.2/gems/fugit-1.5.0/lib/fugit/cron.rb:236:in `loop'
10:04:01 AM worker.1 |  /home/ggallardo/.rvm/gems/ruby-3.0.2/gems/fugit-1.5.0/lib/fugit/cron.rb:236:in `next_time'
10:04:01 AM worker.1 |  /home/ggallardo/.rvm/gems/ruby-3.0.2/gems/rufus-scheduler-3.7.0/lib/rufus/scheduler/jobs_repeat.rb:329:in `set_next_time'
10:04:01 AM worker.1 |  /home/ggallardo/.rvm/gems/ruby-3.0.2/gems/rufus-scheduler-3.7.0/lib/rufus/scheduler/jobs_repeat.rb:281:in `initialize'
10:04:01 AM worker.1 |  /home/ggallardo/.rvm/gems/ruby-3.0.2/gems/rufus-scheduler-3.7.0/lib/rufus/scheduler.rb:711:in `new'
10:04:01 AM worker.1 |  /home/ggallardo/.rvm/gems/ruby-3.0.2/gems/rufus-scheduler-3.7.0/lib/rufus/scheduler.rb:711:in `do_schedule'
10:04:01 AM worker.1 |  /home/ggallardo/.rvm/gems/ruby-3.0.2/gems/rufus-scheduler-3.7.0/lib/rufus/scheduler.rb:226:in `cron'
10:04:01 AM worker.1 |  /home/ggallardo/.rvm/gems/ruby-3.0.2/gems/sidekiq-scheduler-3.1.0/lib/sidekiq-scheduler/scheduler.rb:244:in `new_job'
10:04:01 AM worker.1 |  /home/ggallardo/.rvm/gems/ruby-3.0.2/gems/sidekiq-scheduler-3.1.0/lib/sidekiq-scheduler/scheduler.rb:118:in `block in load_schedule_job'
10:04:01 AM worker.1 |  /home/ggallardo/.rvm/gems/ruby-3.0.2/gems/sidekiq-scheduler-3.1.0/lib/sidekiq-scheduler/scheduler.rb:111:in `each'
10:04:01 AM worker.1 |  /home/ggallardo/.rvm/gems/ruby-3.0.2/gems/sidekiq-scheduler-3.1.0/lib/sidekiq-scheduler/scheduler.rb:111:in `load_schedule_job'
10:04:01 AM worker.1 |  /home/ggallardo/.rvm/gems/ruby-3.0.2/gems/sidekiq-scheduler-3.1.0/lib/sidekiq-scheduler/scheduler.rb:89:in `block in load_schedule!'
10:04:01 AM worker.1 |  /home/ggallardo/.rvm/gems/ruby-3.0.2/gems/sidekiq-scheduler-3.1.0/lib/sidekiq-scheduler/scheduler.rb:87:in `each'
10:04:01 AM worker.1 |  /home/ggallardo/.rvm/gems/ruby-3.0.2/gems/sidekiq-scheduler-3.1.0/lib/sidekiq-scheduler/scheduler.rb:87:in `load_schedule!'
10:04:01 AM worker.1 |  /home/ggallardo/.rvm/gems/ruby-3.0.2/gems/sidekiq-scheduler-3.1.0/lib/sidekiq-scheduler/manager.rb:37:in `start'
10:04:01 AM worker.1 |  /home/ggallardo/.rvm/gems/ruby-3.0.2/gems/sidekiq-scheduler-3.1.0/lib/sidekiq-scheduler.rb:18:in `block (2 levels) in <main>'
10:04:01 AM worker.1 |  /home/ggallardo/.rvm/gems/ruby-3.0.2/gems/sidekiq-6.2.1/lib/sidekiq/util.rb:87:in `block in fire_event'
10:04:01 AM worker.1 |  /home/ggallardo/.rvm/gems/ruby-3.0.2/gems/sidekiq-6.2.1/lib/sidekiq/util.rb:86:in `each'
10:04:01 AM worker.1 |  /home/ggallardo/.rvm/gems/ruby-3.0.2/gems/sidekiq-6.2.1/lib/sidekiq/util.rb:86:in `fire_event'
10:04:01 AM worker.1 |  /home/ggallardo/.rvm/gems/ruby-3.0.2/gems/sidekiq-6.2.1/lib/sidekiq/cli.rb:92:in `run'
10:04:01 AM worker.1 |  /home/ggallardo/.rvm/gems/ruby-3.0.2/gems/sidekiq-6.2.1/bin/sidekiq:31:in `<top (required)>'

)

Expected behaviour

A clear and concise description of what you expected to happen.

Context

ggallardo@ggallardo-Z390-UD:~/tango/api$ uname -a
Linux ggallardo-Z390-UD 5.11.0-25-generic #27~20.04.1-Ubuntu SMP Tue Jul 13 17:41:23 UTC 2021 x86_64 x86_64 x86_64 GNU/Linux
ggallardo@ggallardo-Z390-UD:~/tango/api$ bundle exec ruby -v
ruby 3.0.2p107 (2021-07-07 revision 0db68f0233) [x86_64-linux]
ggallardo@ggallardo-Z390-UD:~/tango/api$ bundle exec ruby -e "p [ :env_tz, ENV['TZ'] ]"
[:env_tz, nil]
ggallardo@ggallardo-Z390-UD:~/tango/api$ bundle exec ruby -r et-orbi -e "EtOrbi._make_info"
(secs:1629209891.538592,utc~:"2021-08-17 14:18:11.5385921001434326",ltz~:"-04")
(etz:nil,tnz:"-04",tziv:"2.0.4",tzidv:nil,rv:"3.0.2",rp:"x86_64-linux",win:false,rorv:nil,astz:nil,eov:"1.2.4",eotnz:#<TZInfo::DataTimezone: America/Santiago>,eotnfz:"-0400",eotlzn:"America/Santiago",eotnfZ:"-04",debian:"America/Santiago",centos:nil,osx:"America/Santiago")
ggallardo@ggallardo-Z390-UD:~/tango/api$ bundle exec ruby -r fugit -e "p Fugit::VERSION"
"1.5.0"
ggallardo@ggallardo-Z390-UD:~/tango/api$ bundle exec ruby -e "p [ :now, Time.now, :zone, Time.now.zone ]
> 

Additional context

Add any other context about the problem here.

cron #previous_time loop breaker issue: modulo plus offset

Issue description

I am not fully confident in what the combination of these two syntaxes is supposed to mean, and the +2 syntax isn’t documented fully in the README, but I believe this user input would be interpreted as every odd Tuesday but only after the first two odd Tuesdays of a month? Which seems to mean “never,” and thus warrant an out of range error.

How to reproduce

require 'fugit'
c = Fugit.parse('0 8 * * 1%2+2')
p c.next_time

Error and error backtrace (if any)

(This should look like:

Traceback (most recent call last):
       16: from /Users/ticky/.rbenv/versions/2.6.5/lib/ruby/gems/2.6.0/gems/bundler-2.1.4/lib/bundler/vendor/thor/lib/thor/base.rb:476:in `start'
       15: from /Users/ticky/.rbenv/versions/2.6.5/lib/ruby/gems/2.6.0/gems/bundler-2.1.4/lib/bundler/cli.rb:30:in `dispatch'
       14: from /Users/ticky/.rbenv/versions/2.6.5/lib/ruby/gems/2.6.0/gems/bundler-2.1.4/lib/bundler/vendor/thor/lib/thor.rb:399:in `dispatch'
       13: from /Users/ticky/.rbenv/versions/2.6.5/lib/ruby/gems/2.6.0/gems/bundler-2.1.4/lib/bundler/vendor/thor/lib/thor/invocation.rb:127:in `invoke_command'
       12: from /Users/ticky/.rbenv/versions/2.6.5/lib/ruby/gems/2.6.0/gems/bundler-2.1.4/lib/bundler/vendor/thor/lib/thor/command.rb:27:in `run'
       11: from /Users/ticky/.rbenv/versions/2.6.5/lib/ruby/gems/2.6.0/gems/bundler-2.1.4/lib/bundler/cli.rb:476:in `exec'
       10: from /Users/ticky/.rbenv/versions/2.6.5/lib/ruby/gems/2.6.0/gems/bundler-2.1.4/lib/bundler/cli/exec.rb:28:in `run'
        9: from /Users/ticky/.rbenv/versions/2.6.5/lib/ruby/gems/2.6.0/gems/bundler-2.1.4/lib/bundler/cli/exec.rb:63:in `kernel_load'
        8: from /Users/ticky/.rbenv/versions/2.6.5/lib/ruby/gems/2.6.0/gems/bundler-2.1.4/lib/bundler/cli/exec.rb:63:in `load'
        7: from /Users/ticky/.rbenv/versions/2.6.5/bin/irb:23:in `<top (required)>'
        6: from /Users/ticky/.rbenv/versions/2.6.5/bin/irb:23:in `load'
        5: from /Users/ticky/.rbenv/versions/2.6.5/lib/ruby/gems/2.6.0/gems/irb-1.2.3/exe/irb:11:in `<top (required)>'
        4: from (irb):4
        3: from /Users/ticky/.rbenv/versions/2.6.5/lib/ruby/gems/2.6.0/gems/fugit-1.4.1/lib/fugit/cron.rb:242:in `next_time'
        2: from /Users/ticky/.rbenv/versions/2.6.5/lib/ruby/gems/2.6.0/gems/fugit-1.4.1/lib/fugit/cron.rb:242:in `loop'
        1: from /Users/ticky/.rbenv/versions/2.6.5/lib/ruby/gems/2.6.0/gems/fugit-1.4.1/lib/fugit/cron.rb:244:in `block in next_time'
RuntimeError (too many loops for "0 8 * * 1%2+2" #next_time, breaking, cron expression most likely invalid (Feb 30th like?), please fill an issue at https://git.io/fjJC9)

)

Expected behaviour

It ought to either return a valid value, or give a descriptive error rather than the loop error.

Context

Darwin Kinzie.home.drac.at 20.1.0 Darwin Kernel Version 20.1.0: Sat Oct 31 00:07:11 PDT 2020; root:xnu-7195.50.7~2/RELEASE_X86_64 x86_64
ruby 2.6.5p114 (2019-10-01 revision 67812) [x86_64-darwin18]
[:env_tz, nil]
(secs:1606760366.633137,utc~:"2020-11-30 18:19:26.6331369876861572",ltz~:"MST")
(etz:nil,tnz:"PST",tziv:"1.2.8",tzidv:nil,rv:"2.6.5",rp:"x86_64-darwin18",win:false,rorv:nil,astz:nil,eov:"1.2.4",eotnz:#<TZInfo::TimezoneProxy: America/Dawson>,eotnfz:"-0700",eotlzn:"America/Dawson",eotnfZ:"MST",debian:nil,centos:nil,osx:"zoneinfo/America/Vancouver")
"1.4.1"

Additional context

Like #30, this is from in-the-wild user input. 😃

cron: mon-thu not respected when L (last day of month)

As reported by @mitnal in jmettraux/rufus-scheduler#270

require 'rufus-scheduler'

#       June 2018
#  Su Mo Tu We Th Fr Sa
#                  1  2
#   3  4  5  6  7  8  9
#  10 11 12 13 14 15 16
#  17 18 19 20 21 22 23
#  24 25 26 27 28 29 30
#
#      July 2018
# Su Mo Tu We Th Fr Sa
#  1  2  3  4  5  6  7
#  8  9 10 11 12 13 14
# 15 16 17 18 19 20 21
# 22 23 24 25 26 27 28
# 29 30 31

p RUBY_VERSION
p RUBY_PLATFORM

ENV['TZ'] = 'Europe/Berlin'

puts
#now = EtOrbi.parse('2018-06-28 18:00:00 Europe/Berlin')
now = Rufus::Scheduler.parse('2018-06-28 18:00:00')
puts "now: " + now.to_s
puts
puts "  '0 9 -2 * *'  9am the second to last day of the month"
puts "3.4.2:  2018-07-29 09:00:00 +0200"
puts "3.5.0:  " + Rufus::Scheduler.parse('0 9 -2 * * Europe/Berlin').next_time(now).to_s
puts
puts "  '0 8 L * mon-thu'  8am the last day of the month (must be a mon or a thu)"
puts "3.4.2:  2018-07-31 08:00:00 +0200"
puts "3.5.0:  " + Rufus::Scheduler.parse('0 8 L * mon-thu Europe/Berlin').next_time(now).to_s
puts
puts "  '0 0 -5 * *' 0am fifth to last day of the month"
puts "3.4.2:  2018-07-26 00:00:00 +0200"
puts "3.5.0:  " + Rufus::Scheduler.parse('0 0 -5 * *').next_time(now).to_s
puts

gives:

"2.4.4"
"x86_64-darwin17"

now: 2018-06-28 18:00:00 +0200

  '0 9 -2 * *'  9am the second to last day of the month
3.4.2:  2018-07-29 09:00:00 +0200
3.5.0:  2018-06-29 09:00:00 +0200

  '0 8 L * * mon-thu'  8am the last day of the month (must be a mon or a thu)
3.4.2:  2018-07-31 08:00:00 +0200
3.5.0:  2018-06-30 08:00:00 +0200

  '0 0 -5 * *' 0am fifth to last day of the month
3.4.2:  2018-07-26 00:00:00 +0200
3.5.0:  2018-07-27 00:00:00 +0200

The second result is wrong. It should give 2018-07-31 08:00:00 +0200 instead (like rufus-scheduler 3.4.2 did).

undefined method `inject' for nil:NilClass

Issue description

undefined method `inject' for nil:NilClass

How to reproduce

c = Fugit::Cron.parse('0 0 * *  sun')
Traceback (most recent call last):
        2: from (irb):10
        1: from (irb):11:in `rescue in irb_binding'
NoMethodError (undefined method `inject' for nil:NilClass)

Natural parsing for specifying days in the month up to the last day

Issue description

Apologies for the issue spamming...

I also need a way to do natural parsing of days of the month up to the last day of the month. I need this because the system I'm building will have users that wish to make themselves unavailable during the last n days of a month where they're closing their financial books off or whatever other things businesses tend to do at the end of the month that makes their people unavailable.

How to reproduce

require 'fugit'

f = Fugit::Nat.parse('every 25th to the last day of the month') # => nil

Expected behaviour

I was expecting to get a cron represenation back that looks a little something like this?

* * 25-L * *

Context

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

Linux a716f734f0ee 4.19.76-linuxkit #1 SMP Tue May 26 11:42:35 UTC 2020 x86_64 GNU/Linux

ruby 2.6.6p146 (2020-03-31 revision 67876) [x86_64-linux]

[:env_tz, nil]

(secs:1601231894.3672342,utc~:"2020-09-27 18:38:14.3672342300415039",ltz~:"UTC")
(etz:nil,tnz:"UTC",tziv:"1.2.7",tzidv:nil,rv:"2.6.6",rp:"x86_64-linux",win:false,rorv:"6.0.3.3",astz:[ActiveSupport::TimeZone, "Etc/UTC"],eov:"1.2.4",eotnz:#<TZInfo::DataTimezone: Etc/UTC>,eotnfz:"+0000",eotlzn:"Etc/UTC",eotnfZ:"UTC",debian:"Etc/UTC",centos:nil,osx:"Etc/UTC")

Additional context

None that I can think of right now...

[Documentation] Regex for crontab notation

Hi,

I'm working on a frontend which lets the user input a crontime to generate a cronjob for sidekiq-cron in the backend.

I'm validating the string backend-wise with your validate method but do you maybe have a regex for doing the validation in the frontend, too? A good documentation which cron string is allowed would also work, of course.

Typical cron regexes didn't work because of your optional 6 digit syntax and so on..

Thank you in advance!

Endless loop after call Fugit::Cron#next_time with time zone 'CST'

environment:

  • ruby 2.3.3p222
  • fugit 1.1.6
  • Time.now.zone is CST(+08:00)

code:

Time.now.utc # "2019-01-02T05:25:53.960Z"
cron = Fugit.do_parse_cron('0 0 1 1 *')
cron.next_time.to_s

expected:

"2019-12-01 00:00:00 +0000"

got:

Endless loop

What I found:

After some debugging, I thought the method TimeCursor#inc_mont doesn't work right in timezone CST (maybe all positive east of UTC timezones).

@t = ::EtOrbi.make(y, m)

This line will parse the year and month as time zone CST, and then transfer to UTC.

For example:

::EtOrbi.make(2019, 2).to_s

expected: 2019-02-01 00:00:00 +0000
but got: 2019-01-31 16:00:00 +0000

The month isn't increased, and the loop in next_time will last forever.

Thank you for your work.

cron #previous_time loop breaker issue

Issue description

A clear and concise description of what the issue is.

How to reproduce

require 'fugit'
c = Fugit.parse('0 9 29 feb *')
p c.previous_time

produces:

/Users/jmettraux/w/fugit/lib/fugit/cron.rb:225:in `block in previous_time': too many loops for "0 9 29 feb *" #previous_time, breaking, please fill an issue at https://git.io/fjJCQ (RuntimeError)
	from /Users/jmettraux/w/fugit/lib/fugit/cron.rb:223:in `loop'
	from /Users/jmettraux/w/fugit/lib/fugit/cron.rb:223:in `previous_time'
	from tst/iteration_count.rb:15:in `<main>'

Expected behaviour

Expected something like:

"2016-2-29 09:00:00 +09:00"

Context

111644 pollux 仁 ~/w/fugit (master) ダ uname -a
Darwin pollux.local 17.7.0 Darwin Kernel Version 17.7.0: Thu Dec 20 21:47:19 PST 2018; root:xnu-4570.71.22~1/RELEASE_X86_64 x86_64
111752 pollux 仁 ~/w/fugit (master) ダ bundle exec ruby -v
ruby 2.3.7p456 (2018-03-28 revision 63024) [x86_64-darwin17]
111752 pollux 仁 ~/w/fugit (master) ダ bundle exec ruby -r et-orbi -e "EtOrbi._make_info"
(secs:1553307474.76292,utc~:"2019-03-23 02:17:54.7629199028015137",ltz~:"JST")
(etz:nil,tnz:"JST",tziv:"2.0.0",tzidv:"1.2018.9",rv:"2.3.7",rp:"x86_64-darwin17",win:false,rorv:nil,astz:nil,eov:"1.1.7",eotnz:#<TZInfo::TimezoneProxy: Asia/Tokyo>,eotnfz:"+0900",eotlzn:"Asia/Tokyo",eotnfZ:"JST",debian:nil,centos:nil,osx:"zoneinfo/Asia/Tokyo")

Additional context

None.

Parse::Nat does not accept every 15 minutes

Issue description

Attempt to parse every 15 minutes

How to reproduce

Nat seems to be able to parse the simplest cases and also 40 minutes, but throw in 30 minutes or 15 minutes and it fails to parse it (which seems a bit unexpected)

require 'fugit'
puts Fugit.parse('every 15 minutes')
puts Fugit.parse('every 30 minutes')
puts Fugit.parse("every 5 minutes")
puts Fugit.parse("every 40 minutes")

Expected behaviour

I expect that it is able to parse every case

Context

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

Darwin fritz-macbook 18.6.0 Darwin Kernel Version 18.6.0: Thu Apr 25 23:16:27 PDT 2019; root:xnu-4903.261.4~2/RELEASE_X86_64 x86_64 i386 MacBookPro14,3 Darwin
ruby 2.6.3p62 (2019-04-16 revision 67580) [x86_64-darwin18]
bundle exec ruby -r et-orbi -e "EtOrbi._make_info"

Additional context

I'm attempting to convert an iso8601 interval to cron output (I'm using sidekiq cron for my databased custom cron jobs but they all use iso8601 interval)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.