Skip to content

Consider sub-second precision #70

Description

@edwardloveall

ActiveSupport's TimeWithZone (and ruby's Time) class support sub-second precision if the host system supports it:

require "rrule"
ruby_time = Time.now # 2025-09-17 12:02:59.535244 -0400
Time.zone = "America/New_York"
time_with_zone = Time.zone.now # Wed, 17 Sep 2025 12:03:18.962661000 EDT -04:00

But rrule does not:

require "rrule"
ruby_time = Time.now # 2025-09-17 12:05:43.144258 -0400
rrule = RRule::Rule.new('FREQ=DAILY;COUNT=5', dtstart: ruby_time)
rrule.all
#[Wed, 17 Sep 2025 16:05:43.000000000 UTC +00:00,
# Thu, 18 Sep 2025 16:05:43.000000000 UTC +00:00,
# Fri, 19 Sep 2025 16:05:43.000000000 UTC +00:00,
# Sat, 20 Sep 2025 16:05:43.000000000 UTC +00:00,
# Sun, 21 Sep 2025 16:05:43.000000000 UTC +00:00]

This can cause some subtle bugs if you're expecting times to match exactly. One example would be generating rrule instances from a set time, adding a duration to that time, and trying to find the matching rrule instance:

require "rrule"
Time.zone = "America/New_York"
time = Time.zone.now # Wed, 17 Sep 2025 12:17:33.014852000 EDT -04:00
rrule = RRule::Rule.new('FREQ=DAILY;COUNT=5', dtstart: time, tzid: "America/New_York")
rrule.all[2]    # Fri, 19 Sep 2025 12:17:33.000000000 EDT -04:00
(time + 2.days) # Fri, 19 Sep 2025 12:17:33.014852000 EDT -04:00
rrule.all[2] == (time + 2.days) # false
rrule.all[2] == (time + 2.days).floor # true

You have to .floor the time which loses precision and is likely not obvious to the developer.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions