Coder Social home page Coder Social logo

et-orbi's People

Contributors

amatsuda avatar dependabot[bot] avatar gogainda avatar jmettraux avatar petergoldstein avatar philr avatar stanhu avatar vais avatar viraptor avatar

Stargazers

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

Watchers

 avatar  avatar  avatar  avatar

et-orbi's Issues

Cannot determine timezone from ActiveSupport::TimeZone

Initially seen at jmettraux/rufus-scheduler#261

Replicated in https://gist.github.com/jmettraux/558216497e746da6490c11f305477e69

#<ActiveSupport::TimeZone:0x00007fc6c28a6868 @name="America/New_York", @utc_offset=nil,
  @tzinfo=#<TZInfo::DataTimezone: America/New_York>>
/Users/jmettraux/.gem/ruby/2.4.2/gems/et-orbi-1.0.7/lib/et-orbi.rb:304:in `initialize':
  Cannot determine timezone from #<ActiveSupport::TimeZone:0x00007fc6c28a6868
  @name="America/New_York", @utc_offset=nil,
  @tzinfo=#<TZInfo::DataTimezone: America/New_York>> (ArgumentError)
(secs:1508824281.618999,
  utc~:"0047-10-24 05:51:21.6189990043640137",ltz~:"EST")
(etz:nil,tnz:"JST",tzid:nil,rv:"2.4.2",rp:"x86_64-darwin14",eov:"1.0.7",
  rorv:"5.1.4",astz:[ActiveSupport::TimeZone, "America/New_York"],
  debian:nil,centos:nil,osx:"Asia/Tokyo")
Try setting `ENV['TZ'] = 'Continent/City'` in your script (see
  https://en.wikipedia.org/wiki/List_of_tz_database_time_zones)
and adding gem 'tzinfo-data'
	from t.rb:14:in `new'
	from t.rb:14:in `<main>'
make: *** [run] Error 1

Ambiguous time when parsing dates with daylight savings using Chronic

Here's a test that reproduces the problem:

diff --git a/spec/module_spec.rb b/spec/module_spec.rb
index a0c980e..893212f 100644
--- a/spec/module_spec.rb
+++ b/spec/module_spec.rb
@@ -288,6 +288,15 @@ describe EtOrbi do
         expect(t.strftime('%Y-%m-%d')).to eq(t1.strftime('%Y-%m-%d'))
         expect(t.strftime('%H:%M:%S')).to eq('12:00:00')
       end
+
+      it 'handles days that have ambiguous daylight savings conversions' do
+
+        Time.active_support_zone = 'America/Chicago'
+
+        t = EtOrbi.parse('2020-11-01 00:00:00')
+
+        expect(t.class).to eq(EtOrbi::EoTime)
+      end
     end
   end

It fails with:

Failures:

  1) EtOrbi.parse when Chronic is defined handles ambiguous daylight savings conversions
     Failure/Error: secs = zone.local_to_utc(local).to_f

     TZInfo::AmbiguousTime:
       Time: 2020-11-01 01:00:00 UTC is an ambiguous local time.
     # ./lib/et-orbi/make.rb:42:in `parse'
     # ./spec/module_spec.rb:296:in `block (4 levels) in <top (required)>'

I described the problem in-depth in https://gitlab.com/gitlab-org/gitlab/issues/37014#note_248974118.

Essentially, when Chronic is used, the time is advanced unnecessarily:

t = Chronic.parse('2020-11-01 00:00:00')
=> 2020-11-01 01:00:00 -0500
str = [ t.strftime('%F %T'), nil ].compact.join(' ')     
=> "2020-11-01 01:00:00"
zone = TZInfo::Timezone.new("America/Chicago")
=> #<TZInfo::DataTimezone: America/Chicago>
zone.local_to_utc(t)
Traceback (most recent call last):
        9: from /opt/gitlab/embedded/bin/irb:23:in `<main>'
        8: from /opt/gitlab/embedded/bin/irb:23:in `load'
        7: from /opt/gitlab/embedded/lib/ruby/gems/2.6.0/gems/irb-1.0.0/exe/irb:11:in `<top (required)>'
        6: from (irb):35
        5: from (irb):35:in `rescue in irb_binding'
        4: from /opt/gitlab/embedded/lib/ruby/gems/2.6.0/gems/tzinfo-1.2.5/lib/tzinfo/timezone.rb:464:in `local_to_utc'
        3: from /opt/gitlab/embedded/lib/ruby/gems/2.6.0/gems/tzinfo-1.2.5/lib/tzinfo/time_or_datetime.rb:324:in `wrap'
        2: from /opt/gitlab/embedded/lib/ruby/gems/2.6.0/gems/tzinfo-1.2.5/lib/tzinfo/timezone.rb:468:in `block in local_to_utc'
        1: from /opt/gitlab/embedded/lib/ruby/gems/2.6.0/gems/tzinfo-1.2.5/lib/tzinfo/timezone.rb:409:in `period_for_local'
TZInfo::AmbiguousTime (Time: 2020-11-01 01:00:00 UTC is an ambiguous local time.)

I propose two ways to solve this here:

  1. An option to disable the use of Chronic
  2. Fix the time zone handling when Chronic is in use

Chronic is probably causing issues because it doesn't handle Daylight Savings well: mojombo/chronic#147

warnings from rspec

I am using rufus, and when i run rspec with tests, I get the following warnings:

/Users/me/.rvm/gems/ruby-2.4.2/gems/et-orbi-1.0.5/lib/et-orbi.rb:608: warning: assigned but unused variable - tu
/Users/me/.rvm/gems/ruby-2.4.2/gems/et-orbi-1.0.5/lib/et-orbi.rb:151: warning: instance variable @local_tzone_loaded_at not initialized
/Users/me/.rvm/gems/ruby-2.4.2/gems/et-orbi-1.0.5/lib/et-orbi.rb:153: warning: instance variable @local_tzone_tz not initialized

I imagine they are easy fixes, and just leftover from some change or another.

Avoid unnecessary calls to Chronic

As seen in sidekiq-cron/sidekiq-cron#276

require 'benchmark'

require 'chronic'
require 'fugit'

# https://github.com/ondrejbartas/sidekiq-cron/issues/276

crons = [ '0 8 1 * * America/Chicago' ] * 1000
time = Time.now

#EtOrbi.chronic_enabled = false
  # leave Chronic parsing enabled (the default as of et-orbi 1.2.3)

puts Benchmark.measure {
  crons.map { |cron| Fugit.parse_cron(cron).previous_time(time).utc }
}.to_s
  #
  # => 109.987803   0.493191 110.480994 (110.569114)
  #
  # ( ruby 2.6.5p114 (2019-10-01 revision 67812) [x86_64-darwin19]
  # ( MacBook Pro mid 2015 16GB RAM

Fugit::Cron#previous_time ends up calling https://github.com/floraison/et-orbi/blob/master/lib/et-orbi/make.rb#L106-L112 so the incoming Time instances ends up as a String and that's where Chronic is called. Do avoid that!

'sub': invalid byte sequence in UTF-8 (ArgumentError)

Related to jmettraux/rufus-scheduler#277

I use rufus-scheduler and I am not sure where to report it but most of the stacktrace mentions this lib:

C:/Ruby24-x64/lib/ruby/gems/2.4.0/gems/et-orbi-1.1.4/lib/et-orbi/zone_aliases.rb:6:in `sub': invalid byte sequence in UTF-8 (ArgumentError)
        from C:/Ruby24-x64/lib/ruby/gems/2.4.0/gems/et-orbi-1.1.4/lib/et-orbi/zone_aliases.rb:6:in `unalias'
        from C:/Ruby24-x64/lib/ruby/gems/2.4.0/gems/et-orbi-1.1.4/lib/et-orbi.rb:156:in `get_tzone'
        from C:/Ruby24-x64/lib/ruby/gems/2.4.0/gems/et-orbi-1.1.4/lib/et-orbi.rb:699:in `determine_local_tzone'
        from C:/Ruby24-x64/lib/ruby/gems/2.4.0/gems/et-orbi-1.1.4/lib/et-orbi.rb:148:in `get_tzone'
        from C:/Ruby24-x64/lib/ruby/gems/2.4.0/gems/et-orbi-1.1.4/lib/et-orbi.rb:269:in `get_tzone'
        from C:/Ruby24-x64/lib/ruby/gems/2.4.0/gems/et-orbi-1.1.4/lib/et-orbi.rb:307:in `initialize'
        from C:/Ruby24-x64/lib/ruby/gems/2.4.0/gems/et-orbi-1.1.4/lib/et-orbi.rb:21:in `new'
        from C:/Ruby24-x64/lib/ruby/gems/2.4.0/gems/et-orbi-1.1.4/lib/et-orbi.rb:21:in `now'
        from C:/Ruby24-x64/lib/ruby/gems/2.4.0/gems/et-orbi-1.1.4/lib/et-orbi.rb:259:in `now'
        from C:/Ruby24-x64/lib/ruby/gems/2.4.0/gems/rufus-scheduler-3.5.2/lib/rufus/scheduler.rb:539:in `start'
        from C:/Ruby24-x64/lib/ruby/gems/2.4.0/gems/rufus-scheduler-3.5.2/lib/rufus/scheduler.rb:88:in `initialize'
        from C:/Users/marce/RubymineProjects/node_alert/main.rb:114:in `new'
        from C:/Users/marce/RubymineProjects/node_alert/main.rb:114:in `<main>'

I am using windows 10. tzinfo is loaded inside the Gemfile.

Simplified code I used to cause this is:

scheduler = Rufus::Scheduler.new
scheduler.every '10m' do
  puts '10'
end

EtOrbi.parse unable to parse some timezones that Time.parse can

I'm trying to parse user-given times for scheduled events, and there are certain timezones parsable by Time and DateTime that are ignored by EtOrbi.

EtOrbi.parse('7AM PST').to_s    # "2021-02-19 07:00:00 +0000"
DateTime.parse('7AM PST').to_s  # "2021-02-19 07:00:00 -0800"
Time.parse('7AM PST').to_s      # "2021-02-19 07:00:00 -0800"

EtOrbi.parse('7AM MDT').to_s    # "2021-02-19 07:00:00 +0000"
Time.parse('7AM MDT').to_s      # "2021-02-19 07:00:00 -0600"

I've done a bit of research and have a suggestion to offer. Perhaps EtOrbi.extract_zone can use Date._parse to determine if the string given has timezone info provided, and if so, use that:

def extract_zone(str)

  s = str.dup

  d = Date._parse(str)
  if d && d[:offset]
    offset = "UTC#{d[:offset] / 3600}"
    s.gsub!(d[:zone], offset) if ZONES_OLSON.include?(offset)
  end
  
  # Rest of original code from method
end

This allows the ZoneOffsets parsable by Time.parse to be recognized here too.

I recognize that there are a small number of timezones affected here, mainly US and military timezones, so maybe it's not worth it? I'd definitely like to hear a maintainer's thoughts.

Thanks!

Master tests broken locally

Ruby version: 2.4.1
Bundler version: 1.15.4
macOS Sierra 10.12.6

When trying to run the tests locally, the following failures occur:

Failures:

  1) EtOrbi.make_time turns a Date instance into an EoTime instance
     Failure/Error:
       fail ArgumentError.new(
         "cannot determine timezone from #{zone.inspect}" +
         "\n#{render_nozone_time(s)}" +
         "\n#{self.class.platform_info.sub(',debian:', ",\ndebian:")}" +
         "\nTry setting `ENV['TZ'] = 'Continent/City'` in your script " +
         "(see https://en.wikipedia.org/wiki/List_of_tz_database_time_zones)" +
         (defined?(TZInfo::Data) ? '' : "\nand adding gem 'tzinfo-data'")
       ) unless @zone

     ArgumentError:
       cannot determine timezone from "CDT"
       (secs:1477976400.0,utc~:"0046-11-01 05:00:00.0",ltz~:"LMT")
       (etz:nil,tnz:"CDT",tzid:nil,rv:"2.4.1",rp:"x86_64-darwin16",eov:"1.0.6",rorv:nil,astz:nil,
       debian:nil,centos:nil,osx:"America/Chicago")
       Try setting `ENV['TZ'] = 'Continent/City'` in your script (see https://en.wikipedia.org/wiki/List_of_tz_database_time_zones)
       and adding gem 'tzinfo-data'
     # ./lib/et-orbi.rb:244:in `initialize'
     # ./lib/et-orbi.rb:96:in `new'
     # ./lib/et-orbi.rb:96:in `make_from_time'
     # ./lib/et-orbi.rb:101:in `make_from_date'
     # ./lib/et-orbi.rb:75:in `make_time'
     # ./spec/module_spec.rb:491:in `block (5 levels) in <top (required)>'
     # ./spec/spec_helper.rb:22:in `in_zone'
     # ./spec/module_spec.rb:485:in `block (4 levels) in <top (required)>'

  2) EtOrbi.make_time turns a String into an EoTime instance
     Failure/Error: else expect(eot).to eq(exp)

       expected: #<EtOrbi::EoTime:0x007f97e6387770 @seconds=1478021409.0, @zone=#<TZInfo::TimezoneProxy: America/Bahia_Banderas>, @time=nil>
            got: #<EtOrbi::EoTime:0x007f97e71771c8 @seconds=1478025009.0, @zone=#<TZInfo::TimezoneProxy: America/Bahia_Banderas>, @time=nil>

       (compared using ==)

       Diff:
       @@ -1,5 +1,5 @@
       -#<EtOrbi::EoTime:0x007f97e6387770
       - @seconds=1478021409.0,
       +#<EtOrbi::EoTime:0x007f97e71771c8
       + @seconds=1478025009.0,
         @time=nil,
         @zone=#<TZInfo::TimezoneProxy: America/Bahia_Banderas>>

     # ./spec/module_spec.rb:502:in `block (4 levels) in <top (required)>'

  3) EtOrbi::EoTime#monthdays returns the appropriate "0#2"-like string
     Failure/Error: expect(mds(local(1970, 1, 1))).to eq(%w[ 4#1 4#-5 ])

       expected: ["4#1", "4#-5"]
            got: ["3#5", "3#-1"]

       (compared using ==)
     # ./spec/time_spec.rb:266:in `block (3 levels) in <top (required)>'

Finished in 0.09694 seconds (files took 0.86364 seconds to load)
73 examples, 3 failures

Failed examples:

rspec ./spec/module_spec.rb[1:8:6] # EtOrbi.make_time turns a Date instance into an EoTime instance
rspec ./spec/module_spec.rb[1:8:7] # EtOrbi.make_time turns a String into an EoTime instance
rspec ./spec/time_spec.rb:264 # EtOrbi::EoTime#monthdays returns the appropriate "0#2"-like string

This is from running bundle exec rspec, which I found is the expected way to run tests from the latest CI run, which is indeed passing. I'm on the same SHA as that run, too (ff967e8).

I would assume this is probably a Mac issue.

stack level too deep in `now` on Windows

As reported for rufus-scheduler at jmettraux/rufus-scheduler#269

Reproduced on Appveyor at https://ci.appveyor.com/project/jmettraux/et-orbi/build/job/p80wb2e7flbbd6oo?fullLog=true#L202 :

[00:00:17]   2) EtOrbi.make_time turns a Date instance into an EoTime instance
[00:00:17]      Failure/Error:
[00:00:17]        tabbs = (-6..5)
[00:00:17]          .collect { |i| (Time.now + i * 30 * 24 * 3600).zone }
[00:00:17]          .uniq
[00:00:17]          .sort
[00:00:17]          .join('|')
[00:00:17] 
[00:00:17]      SystemStackError:
[00:00:17]        stack level too deep
[00:00:17]      # ./lib/et-orbi.rb:697:in `now'
[00:00:17]      # ./lib/et-orbi.rb:697:in `block in determine_local_tzones'
[00:00:17]      # ./lib/et-orbi.rb:697:in `each'
[00:00:17]      # ./lib/et-orbi.rb:697:in `collect'
[00:00:17]      # ./lib/et-orbi.rb:697:in `determine_local_tzones'
[00:00:17]      # ./lib/et-orbi.rb:630:in `determine_local_tzone'
[00:00:17]      # ./lib/et-orbi.rb:146:in `get_tzone'
[00:00:17]      # ./lib/et-orbi.rb:262:in `get_tzone'
[00:00:17]      # ./lib/et-orbi.rb:300:in `initialize'
[00:00:17]      # ./lib/et-orbi.rb:19:in `new'
[00:00:17]      # ./lib/et-orbi.rb:19:in `now'
[00:00:17]      # ./lib/et-orbi.rb:252:in `now'
[00:00:17]      # ./lib/et-orbi.rb:188:in `platform_info'
[00:00:17]      # ./lib/et-orbi.rb:305:in `initialize'
[00:00:17]      # ./lib/et-orbi.rb:19:in `new'
[00:00:17]      # ./lib/et-orbi.rb:19:in `now'
[00:00:17]      # ./lib/et-orbi.rb:252:in `now'
[00:00:17]      # ./lib/et-orbi.rb:188:in `platform_info'
[00:00:17]      # ...

for

[00:00:17] rspec './spec/module_spec.rb[1:8:6]' # EtOrbi.make_time turns a Date instance into an EoTime instance

@_os_zone not initialized

Hello, I'm getting this warning printed when running a test suite.

gems/et-orbi-1.1.3/lib/et-orbi.rb:675: warning: instance variable @_os_zone not initialized

The code imports rufus-scheduler and uses it like:

@@scheduler = LazyObject.new { Rufus::Scheduler.new }
def scheduler; @@scheduler; end

What is missing to be able to not have this warning? Thanks!

Timezone ignored in cron.match?

Timezone seems to be completely irrelevant when calling match? on cron object:

> cron = Fugit::Cron.parse("0 0 * * * PST8PDT")
=> #<Fugit::Cron:0x00007ff5e1422e60 @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>>

> cron.match?(Time.utc(2019, 1, 1, 0, 0, 0))
=> true

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

> cron.match?(Time.new(2019, 1, 1, 0, 0, 0, TZInfo::Timezone.get('CET')))
=> true

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

I thought setting timezone in cron would make it only match in specific time zone. In example above i'd expect it to match only in PST8PDT midnight.

Issue with get_tzone blowing up

I'm using Rails 2.3, rufus-scheduler 3.4, resque-scheduler 4.3, and tzinfo 0.3.53, et-orbi 1.0.3

When I start the scheduler, I'm getting

NoMethodError: undefined method `identifier' for nil:NilClass
.rvm/gems/ruby-2.3.3/gems/tzinfo-0.3.53/lib/tzinfo/timezone.rb:502:in `<=>'
.rvm/gems/ruby-2.3.3/gems/et-orbi-1.0.3/lib/et-orbi.rb:92:in `=='

What I'm finding is that I have a timezone set for the get_tzone function and it doesn't know how to respond to the == nil or the == :local from lines 92 and 93.

In order to make it work, I simply moved the return if you have a timezone above the nil and local check so it now looks like

return o if o.is_a?(::TZInfo::Timezone)
return nil if o == nil
return local_tzone if o == :local
return ::TZInfo::Timezone.get('Zulu') if o == 'Z'

Time error in sidekiq-cron

The issue:
sidekiq-cron is giving following error.

2019-09-03T13:53:00.672Z 960 TID-owuukgjt0 ERROR: CRON JOB: /.rvm/gems/ruby-2.2.2@views/gems/sidekiq-cron-0.3.1/lib/sidekiq/cron/job.rb:434:in `<'
2019-09-03T13:53:15.692Z 960 TID-owuukgjt0 ERROR: CRON JOB: comparison of Time with EtOrbi::EoTime failed.
2019-09-03T13:53:15.692Z 960 TID-owuukgjt0 ERROR: CRON JOB: /.rvm/gems/ruby-2.2.2@views/gems/sidekiq-cron-0.3.1/lib/sidekiq/cron/job.rb:434:in `<'
2019-09-03T13:53:30.711Z 960 TID-owuukgjt0 ERROR: CRON JOB: comparison of Time with EtOrbi::EoTime failed

EtOrbi::EoTime#to_time ignores timezone, produces wrong values

Should be pretty self explanatory - I believe I'm using the most recent version. Below is an illustrative snippet:

require 'et_orbi'
# => true
EtOrbi::VERSION
# => "1.0.5"
puts EtOrbi.platform_info
# (etz:nil,tnz:"UTC",tzid:nil,rv:"1.9.3",rp:"x86_64-linux",eov:"1.0.5",rorv:nil,astz:nil,debian:nil,centos:nil,osx:"UTC")
# => nil
my_time = EtOrbi.make_time(2017, 1, 31, 12, 'Europe/Moscow')
# => 2017-01-31 12:00:00 +0300
my_time.to_time
# => 2017-01-31 12:00:00 UTC
my_time.to_i
# => 1485853200
my_time.to_time.to_i
# => 1485864000

It might make sense to use the system timezone for #to_time, but I would have expected it to at act more like:

Time.at(my_time.to_f)

Which incidentally is what I'm currently using as a workaround. For a bit of background, I'm using this through the Rufus::Scheduler gem.

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.