Giter Site home page Giter Site logo

#next_time breaks on DST end about fugit HOT 4 OPEN

trafium avatar trafium commented on July 24, 2024
#next_time breaks on DST end

from fugit.

Comments (4)

jmettraux avatar jmettraux commented on July 24, 2024

Hello,

as a preliminary remark, a reminder that Time.parse(str) does not care about time zones:

# ruby 3.2.2 (2023-03-30 revision e51014f9c0) [x86_64-openbsd7.4]

require 'time'


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

p Time.now
  # 2024-03-26 01:19:30.188064864 +0200

p Time.parse("2012-10-28 02:59:00 EEST")
p Time.parse("2012-10-28 02:59:00 Europe/Tallinn")
  # 2012-10-28 02:59:00 +0300
  # 2012-10-28 02:59:00 +0300

p Time.parse("2012-10-28 02:59:00 Some/Where")
p Time.parse("2012-10-28 02:59:00 XXX")
  # 2012-10-28 02:59:00 +0300
  # 2012-10-28 02:59:00 +0300



ENV['TZ'] = 'Asia/Tokyo'

p Time.now
  # 2024-03-26 08:19:30.18919636 +0900

p Time.parse("2012-10-28 02:59:00 EEST")
p Time.parse("2012-10-28 02:59:00 Europe/Tallinn")
  # 2012-10-28 02:59:00 +0900
  # 2012-10-28 02:59:00 +0900

p Time.parse("2012-10-28 02:59:00 Some/Where")
p Time.parse("2012-10-28 02:59:00 XXX")
  # 2012-10-28 02:59:00 +0900
  # 2012-10-28 02:59:00 +0900

from fugit.

jmettraux avatar jmettraux commented on July 24, 2024

Tinkering:

# ruby 3.2.2 (2023-03-30 revision e51014f9c0) [x86_64-openbsd7.4]

require 'fugit'

ENV['TZ'] = 'Europe/Tallinn'
  # approximating OP's situation...


p Fugit::Cron.parse("*/1 * * * *")
  .next_time(Time.parse("2012-10-28 02:59:00 EEST")).to_t
    # => 2012-10-28 03:00:00 +0300  ## because ENV TZ is Europe/Tallinn
p Fugit::Cron.parse("*/1 * * * *")
  .next_time(Fugit.parse("2012-10-28 02:59:00 EEST")).to_t
    # => 2012-10-28 10:00:00 +0200  ## off
p Fugit::Cron.parse("*/1 * * * *")
  .next_time(Fugit.parse("2012-10-28 02:59:00 Europe/Tallin")).to_t
    # => 2012-10-28 03:00:00 +0300 ## OK

##

#p Fugit::Cron.parse("*/1 * * * *")
#  .next_time(Time.parse("2012-10-28 02:59:00 EEST") + 1.minute)
#p Fugit::Cron.parse("*/1 * * * *")
#  .next_time(Time.parse("2012-10-28 02:59:00 EEST") + 60)
#p Fugit::Cron.parse("*/1 * * * *")
#  .next_time(Fugit.parse("2012-10-28 02:59:00 EEST") + 60).to_t
p Fugit::Cron.parse("*/1 * * * *")
  .next_time(Fugit.parse("2012-10-28 02:59:00 Europe/Tallin") + 60).to_t
    # => 2012-10-28 03:01:00 +0300
#/Users/traf/.rbenv/versions/3.2.3/lib/ruby/gems/3.2.0/gems/et-orbi-1.2.11/lib/et-orbi/time.rb:82
#   :in `initialize': Cannot determine timezone from "EEST" (ArgumentError)

##

#p Fugit::Cron.parse("*/1 * * * *")
#  .next_time(Time.parse("2012-10-28 03:00:00 EEST")).to_t
p Fugit::Cron.parse("*/1 * * * *")
  .next_time(Fugit.parse("2012-10-28 03:00:00 EEST")).to_t
    # => 2012-10-28 10:01:00 +0200
p Fugit::Cron.parse("*/1 * * * *")
  .next_time(Fugit.parse("2012-10-28 03:00:00 Europe/Tallinn")).to_t
    # => ~/.gem/ruby/3.2.2/gems/et-orbi-1.2.11/lib/et-orbi/make.rb:65
    #      :in `make_time': Cannot turn nil to a ::EtOrbi::EoTime instance
    #      (ArgumentError)
	#      from ~/w/fugit/lib/fugit/cron.rb:247:in `next_time'
p Fugit.parse("2012-10-28 03:00:00 Europe/Tallinn")
  # => nil
p EtOrbi.parse("2012-10-28 03:00:00 Europe/Tallinn")
  # => ~/.gem/ruby/3.2.2/gems/tzinfo-2.0.6/lib/tzinfo/timezone.rb:525:in `period_for_local':
  #         2012-10-28 03:00:00 is an ambiguous local time. (TZInfo::AmbiguousTime)
  # from ~/.gem/ruby/3.2.2/gems/tzinfo-2.0.6/lib/tzinfo/timezone.rb:652:in `block in local_to_utc'
  # from ~/.gem/ruby/3.2.2/gems/tzinfo-2.0.6/lib/tzinfo/timestamp.rb:144:in `for'
  # from ~/.gem/ruby/3.2.2/gems/tzinfo-2.0.6/lib/tzinfo/timezone.rb:648:in `local_to_utc'
  # from ~/.gem/ruby/3.2.2/gems/et-orbi-1.2.11/lib/et-orbi/make.rb:46:in `parse'
p (Fugit.parse("2012-10-28 02:59:00 Europe/Tallinn") + 60).to_t
  # => 2012-10-28 03:00:00 +0300

##

#p Fugit::Cron.parse("*/1 * * * *")
#  .next_time(Time.parse("2012-10-28 02:59:00 Europe/Tallinn") + 1.minute)
#p Fugit::Cron.parse("*/1 * * * *")
#  .next_time(Time.parse("2012-10-28 02:59:00 Europe/Tallinn") + 60)
p Fugit::Cron.parse("*/1 * * * *")
  .next_time(Fugit.parse("2012-10-28 02:59:00 Europe/Tallinn") + 60).to_t
    # => 2012-10-28 03:01:00 +0300

from fugit.

jmettraux avatar jmettraux commented on July 24, 2024

Further tinkering:

This works:

require 'fugit'

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

#c = Fugit.parse_cron('*/1 * * * *') # equivalent to
c = Fugit.parse_cron('* * * * *')

t = Fugit.parse('2012-10-28 02:59:00 Europe/Tallinn')

70.times do |i|
  puts "%2d - %s" % [ i, t ? t.to_t.inspect : 'nil' ]
  t = c.next_time(t)
end

It transitions smoothly:

...
58 - 2012-10-28 03:57:00 +0300
59 - 2012-10-28 03:58:00 +0300
60 - 2012-10-28 03:59:00 +0300
61 - 2012-10-28 03:00:00 +0200
62 - 2012-10-28 03:01:00 +0200
63 - 2012-10-28 03:02:00 +0200
...

But making it start at '2012-10-28 03:00:00 Europe/Tallinn' instead of '2012-10-28 02:59:00 Europe/Tallinn' has nil for t and it fails immediately. Fugit.parse('2023-10-28 03:00:00') (in Europe/Tallinn) also returns nil.

I need to find a way in fugit or et-orbi to return the right time when parsing an ambiguous timezone.

I will go on investigating tonight after work. Thanks for reporting that.

from fugit.

trafium avatar trafium commented on July 24, 2024

Thanks @jmettraux, I was unaware of that weird behaviour of Time.parse with time zones. Still trying to grasp what is going on exactly though.

But keeping that in mind, I found out that I can use Time.find_zone!("Europe/Tallinn").parse("2012-10-28 02:59:00") which gives me ActiveSupport::TimeWithZone and it does not break in Fugit that way.

Time.find_zone!("Europe/Tallinn").parse("2012-10-28 02:59:00") + 1.minute
#=> Sun, 28 Oct 2012 03:00:00.000000000 EEST +03:00
(Time.find_zone!("Europe/Tallinn").parse("2012-10-28 02:59:00") + 1.minute).zone
#=> "EEST"
(Time.find_zone!("Europe/Tallinn").parse("2012-10-28 02:59:00") + 1.minute).dst?
#=> true
(Time.find_zone!("Europe/Tallinn").parse("2012-10-28 02:59:00") + 1.minute) == (Time.parse("2012-10-28 02:59:00 Europe/Tallinn") + 1.minute)
#=> true
(Time.find_zone!("Europe/Tallinn").parse("2012-10-28 02:59:00") + 1.minute).zone == (Time.parse("2012-10-28 02:59:00 Europe/Tallinn") + 1.minute).zone
#=> true
(Time.find_zone!("Europe/Tallinn").parse("2012-10-28 02:59:00") + 1.minute).dst? == (Time.parse("2012-10-28 02:59:00 Europe/Tallinn") + 1.minute).dst?
#=> true
Fugit::Cron.parse("*/1 * * * *").next_time(Time.find_zone!("Europe/Tallinn").parse("2012-10-28 02:59:00") + 1.minute).to_t
#=> 2012-10-28 03:01:00 +0300
Fugit::Cron.parse("*/1 * * * *").next_time(Time.find_zone!("Europe/Tallinn").parse("2012-10-28 03:59:00")).to_s
#=> "2012-10-28 03:00:00 +0200"

from fugit.

Related Issues (20)

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.