Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

returned date incorrect caused by TZ rollover #610

Open
2 tasks done
sdetweil opened this issue Dec 13, 2023 · 5 comments
Open
2 tasks done

returned date incorrect caused by TZ rollover #610

sdetweil opened this issue Dec 13, 2023 · 5 comments

Comments

@sdetweil
Copy link

sdetweil commented Dec 13, 2023

Reporting an issue

Thank you for taking an interest in rrule! Please include the following in
your report:

  • [X ] Verify that you've looked through existing issues for duplicates before
    creating a new one
  • [X ] Code sample reproducing the issue. Be sure to include all input values you
    are using such as the exact RRule string and dates.
  • [X ] Expected output
  • [X ] Actual output
  • The version of rrule you are using
  • Your operating system
  • [x ] Your local timezone (run $ date from the command line
    of the machine showing the bug)

os info

uname -a
Linux sams 5.15.0-88-generic #98-Ubuntu SMP Mon Oct 2 15:18:56 UTC 2023 x86_64 x86_64 x86_64 GNU/Linux

lsb_release -a
No LSB modules are available.
Distributor ID:	Ubuntu
Description:	Ubuntu 22.04.3 LTS
Release:	22.04
Codename:	jammy

local tz, America/Denver
Wed Dec 13 01:40:55 PM MST 2023

sample code

const RRule=require("rrule").RRule
const datetime= require("rrule").datetime;
const Log=console

	let rule = new RRule({
		  freq: RRule.WEEKLY,
  	           interval: 1,
                  byweekday: [RRule.WE],
		  dtstart: 	datetime(2023, 12, 14, 00, 15, 00),  //20231206T171500
		  count: 5,
		  tzid: 'America/Denver',
		})

	let results=rule.all()
	console.log("all dates="+JSON.stringify(results,null,2))

results

all dates=[
                                                    // because of the wrong date, todays event is clipped off 2023:12:13T17:15:00 MST
  "2023-12-20T00:15:00.000Z",  // this is tuesday 2023-12-11T17:15:00 in local tz, not wednesday 
  "2023-12-27T00:15:00.000Z",
  "2024-01-03T00:15:00.000Z",
  "2024-01-10T00:15:00.000Z",
  "2024-01-17T00:15:00.000Z"
]

from package,json

{
  "name": "rrule",
  "version": "2.8.1",

remove tzid no change

@Reeywhaar
Copy link

Basically this library is full of footguns because it tries to rely on bare Date object and stores everything in utc. If it use moment or analog it would be like 4x smaller and cleaner. So this is it. Number of issues says it all.

@sdetweil
Copy link
Author

@Reeywhaar general criticism is not helpful. you are welcome to show your talent and provide a better solution. I don't have time or the inclination

our app uses an ICS parser that uses this library. and I support the calendar component, so I'm sorta stuck.

@Reeywhaar
Copy link

Reeywhaar commented Jan 12, 2024

In my case what I've done is stopped using tzid parameter in rrule completely. What I do now is I receive dtstart, assign it local timezone (in case of moment library this is moment(dtstart).local(true)) so 05:00 in some dtstart timezone becomes 05:00 in whatever local time it is. Then I find occurences and reassign original timezone to received results: results.map((d: Date) => moment(d).tzid(dtstartTimezone, true) ).

So basically I don't use anything tz related in rrule because this is unreliable as hell. All incoming parameters in rrule are in local timezone.
Local timezone is treated by rrule as timezone without offset, i.e literal time. So 09:00 remains 09:00 no matter what dst mark it passes.

Also in case of finding occurences you have to convert incoming parameters (after and before). First to timezone of dtstart, and then assign local timezone.

@jonnytest1
Copy link

jonnytest1 commented Jan 24, 2024

here is my fix :

`
from dateutil.rrule import rrulestr
from datetime import datetime
import sys

inputtime = sys.argv[1]
rules = sys.argv[2].split("RRULE:")[1] #

start = datetime.fromtimestamp(float(inputtime)/1000)

ruleObj = rrulestr(rules, dtstart=start)
next = ruleObj.after(datetime.now())
print(next.isoformat())

const response = spawnSync(python, [join(__dirname, "rrule.py"), ${+date}, rule], { encoding: "utf8" })
return new Date(response.stdout.trim())
`
works liek a charm 🤣 (sry i just spent half a day on this )

@juni0r
Copy link

juni0r commented Feb 16, 2024

I'm sure this library can do a lot of things. Creating date recurrences that respect timezones and daylight saving times unfortunately isn't one of them. If you want to do this, you've picked the wrong tool.

Anyone who ends up here, might want to check out rschedule. It comes with adapters for many popular date libraries, such as moment.js and Luxon, as well as vanilla JS Date. It doesn't see much activity and documentation isn't exactly exhaustive, but from the few usage examples and the codesandbox one will quickly figure out how to use it. It sports a modular approach and pluggable features, such as JSON and iCal support.

Hope this helps.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants