Show HN: Cronexpr, a Rust library to parse and iter crontab expression
docs.rs
docs.rs
And when I sorted out the parse structure [1] and finished the extensions [2][3], I believe I should write it down for others (and future me) :D
[1] https://github.com/tisonkun/cronexpr/pull/4
[1] https://github.com/hexagon/croner-rust?tab=readme-ov-file#wh...
As supported in [2],
> There are several good candidates like croner and saffron, but they are not suitable for my use case. Both of them do not support defining timezone in the expression which is essential to my use case. Although croner support specific timezone later when matching, the user experience is quite different. Also, the syntax that croner or saffron supports is subtly different from my demand. > > Other libraries are unmaintained or immature to use. > > Last, most candidates using chrono to processing datetime, while I’d prefer to extend the jiff ecosystem.
[2] https://docs.rs/cronexpr/latest/cronexpr/#why-do-you-create-...
... and this PR [1][2]
[1] https://github.com/tisonkun/cronexpr/pull/12
[2] https://docs.rs/cronexpr/latest/cronexpr/struct.Crontab.html...
For an API, I could see either taking in something that is hashable or just taking in a number and letting the caller choose their hashing. From the person's perspective writing cron syntax, they shouldn't care so long as they get the intended affect.
In cronexpr, there is no requirement for a timestamp until you'd like to find the next scheduled time, and thus you need to provide a related point.
To decouple with certain datetime lib, I made a `MakeTimestamp` struct which provides multiple constructors. Later, I found it somehow like a function overload :D
[1] https://docs.rs/cronexpr/latest/cronexpr/#why-does-the-crate...
Assuming UTC for tz is not weird and cron users expect it,
I guess why even support this specific syntax if the crons need to be edited to fit how this code expects them? There may have been better options if you were going full green field.
Good work though!
That would definitely be weird and unexpected. My crons are interpreted with respect to my system's configured time zone, which seems way more expected than just using UTC.
Taking a datetime and just assuming it's UTC is often a mistake. It's why the TC39 Temporal proposal (overhauling datetimes for Javascript) won't let you silently do it.
1. Optional Timezone.
2. Second-level precision (perhaps feature flags are more suitable here)
It just falls out my first requirements so I don't support it. Being too generic is a common source of failure in my experience.
As a library developer I have my opinion on how things should be done and provide the default fits that mind :D
I think you're confusing systemd timer units with Cronie[0], a crond implementation that I think predates systemd? It's possible there's some systemd thing I don't know about though!
I think most distros at least have an installable crond
It also has a cron scheduler [0] which includes scheduling down to seconds and perfectly integrates with asyncio [1].
async def myfunc():
print(f"\n{Fore.GREEN}Readout triggered at { datetime.now().strftime('%H:%M:%S') }{COLORS_RESET}\n")
await disk_temperatures_handler.readout(storage)
scheduler = AsyncIOScheduler()
storage['scheduler'] = scheduler
scheduler.add_job(myfunc, CronTrigger(second='*/15'), id='readout_job')
scheduler.start()
You can also modify the interval on-the-fly.[0] https://apscheduler.readthedocs.io/en/3.x/modules/triggers/c...
[1] https://apscheduler.readthedocs.io/en/3.x/modules/executors/...
I never really liked cronjob expressions.
That should give you all the information you need to determine if it got the right expression.
In this case I think it's better to run known, deterministic code that can turn a crontab into a clear explanation.