Skip to content

Releases: simpllyf/hron

v2.0.0

Choose a tag to compare

@prasrvenkat prasrvenkat released this 02 Oct 04:36
Immutable release. Only release title and notes can be modified.
e28b127

hron 2.0.0

hron 2.0 makes every implementation keep one exact contract. The same expression gives the same occurrences, the same cron conversion, the same error message and span, and the same public API in Rust, TypeScript, WebAssembly, Python, Go, Java, C#, Ruby and Dart. Shared spec files define that contract, and every package's tests run against them (#84, #95, #96, #98, #99, #101). This release also adds a ninth implementation, a native Swift package (#102).

It is a major version because getting there changes public APIs in every package. Some names are renamed, internals are no longer exported, and schedules can no longer be changed after they are built. Wrong-type and null arguments now raise each platform's own usage error. Some inputs that used to parse are now rejected, and every error message has new text. Each break is listed below by package.

Highlights

  • One contract, checked everywhere. spec/tests.json gained hundreds of fixed-answer cases and a set of invariants (#84). spec/build.json covers schedules built in code (#99), and spec/api.json covers the public API of every language (#101). Each runner fails on any case it cannot check (#84).
  • Correct evaluation in every language. The implementations used to disagree on more than a thousand generated cases, and in 735 more they agreed on a wrong answer. These are fixed, and DST handling is now the same in every zone (#84). Searches find occurrences that lie past one-off except dates (#88).
  • Invalid schedules fail at parse time. Once a schedule parses, evaluating it cannot fail (#85).
  • Exact cron conversion. fromCron and toCron give a schedule that fires at the same local times on the same dates, or they fail with a clear message (#95).
  • One error per mistake. Every lex and parse error has the same kind, message, span and suggestion in every language, and spans count Unicode code points (#96).
  • Timestamps are instants. Timestamp arguments are read as instants, and results come back in the schedule's zone, or in UTC when the schedule has none (#98).
  • Immutable schedules with getters and equality. A schedule cannot change after it is built. It has six read-only getters, and two schedules are equal when their parts are equal (#99, #101).
  • Faster. All nine evaluators share one search design. In a stress set of DST cases, total evaluation time fell in every language, for example Go from 30s to 14s and Java from 4.9s to 2.5s (#89, #90, #91, #92).
  • New: Swift. A native Swift package with no dependencies, installed with SwiftPM (#102).
  • New home. The repository is now github.com/simpllyf/hron, and the Go module path is now github.com/simpllyf/hron/go/v2 (#94).

Breaking changes by package

Changes that apply to every package are described under Behaviour changes: stricter parsing (#85, #96), new error message text (#95, #96), and some fromCron results written in a different form (#95).

Rust: hron (crates.io)

  • Schedule::from_parts(ScheduleParts) -> Result and to_parts() replace Schedule::new and the with_timezone, with_except, with_until, with_anchor and with_during methods. Parts are checked with the same rules as parse, and a bad part fails with an eval error (#99).
  • Evaluation can no longer fail, so next_from, previous_from, next_n_from and matches return their values directly instead of a Result, and the occurrences and between iterators yield Zoned (#99).
  • Schedule::expr() is renamed to expression(), and anchor() is renamed to starting() (#101).
  • Error spans count Unicode code points, not bytes. Span keeps its type, so code that slices the input with a span must convert it. The README shows how (#96).

Also new: Hash is implemented on Schedule and on every part type. ErrorKind is new, and ScheduleError gains the accessors kind(), message(), span(), input() and suggestion(). ErrorKind and Span are re-exported at the crate root (#101).

CLI: hron-cli (crates.io and release binaries)

  • --n is replaced by -n/--count (#101).
  • --from without -n prints one occurrence, not up to 100 (#101).
  • A usage error exits with status 2 (#98).
  • -n together with --to is now a usage error. So is --explain or --from-cron together with an expression, or the two together (#101).

Also changed: --from and --to take the same RFC 9557 or RFC 3339 strings as WebAssembly, with an offset or Z, and negative years are accepted (#98). --json prints [] when nothing is found (#101). Without --to, an empty result now prints the note "no occurrences after --from" (#101). Piping the output to head no longer panics (#98).

WebAssembly: hron-wasm (npm)

  • A timestamp string without an offset is rejected. Strings may be RFC 9557 or RFC 3339, with an offset or Z, including Date.prototype.toISOString() output (#98).
  • An argument of the wrong type throws TypeError, and a bad value throws RangeError. Both used to trap with RuntimeError: memory access out of bounds (#98).
  • An n or limit of 0 or less returns [], where -1 used to wrap to 4294967295. A non-integer such as 1.5 throws (#98).
  • toJSON() returns a plain object, where it used to return a Map that serialized as {}. Absent fields are null (#98).
  • timezone, nextFrom and previousFrom return null instead of undefined (#101).
  • A non-string input to parse, validate, fromCron or explainCron throws TypeError. A number used to trap (#101).

Also new: explainCron is exported, as its README already showed (#95). Errors carry kind (#95), plus span, suggestion, input and displayRich() (#96). New getters return the same plain objects as hron-ts, frozen at every level, and there is a new equals(other). The .d.ts now types the part types, HronError, HronErrorKind and Span (#101). Array returns are typed string[] (#98).

TypeScript: hron-ts (npm)

  • Timestamp arguments are checked when the method is called. Temporal.ZonedDateTime and Temporal.Instant are accepted, native or polyfilled, and anything else is a TypeError (#98).
  • A non-integer n is a RangeError. nextNFrom(now, 1.5) used to run to the end of the supported range (#98).
  • occurrences and between reject bad arguments when they are called, not on the first next() (#98).
  • expression is deeply frozen, and the AST types are readonly (#99).
  • new Schedule(...) called from JavaScript throws. Build schedules with parse or fromCron (#99).
  • A non-string input to parse, validate or fromCron throws TypeError, and validate no longer returns false for one (#101).
  • validate no longer swallows errors that are not a HronError (#101).
  • The HronError constructors throw TypeError for a bad message, input, suggestion or span (#101).
  • The ScheduleData type export is removed (#101).
  • Error spans count Unicode code points, not UTF-16 code units. The numbers change only for input that contains characters outside the Basic Multilingual Plane (#96).

Also new: the getters except, until, starting and during, which return frozen values, and equals(other). NearestDirection is now exported (#101).

Python: hron (PyPI)

  • ScheduleData(expr=..., anchor=...) is now ScheduleData(expression=..., starting=...) (#101).
  • HronError.input_text is now HronError.input (#101).
  • A non-str input to parse, validate or from_cron raises TypeError (#101).
  • HronError(...) and its constructors raise TypeError for an argument of the wrong type (#101).
  • ScheduleData is frozen, and its lists are tuples (#99).
  • Schedule(ScheduleData(...)) checks its parts with the same rules as parse, and a value of the wrong type is a TypeError (#99).
  • The internal to_cron, display, parse and the like can no longer be imported from hron (#99).
  • A timestamp argument that is not a datetime raises TypeError, not AttributeError (#98).
  • n is converted with operator.index, so a non-integer n raises TypeError (#98).

Also new: the properties except_, until, starting and during, and HronError.message (#101). Schedule has value equality and a data property, and NearestWeekdayTarget and NearestDirection are exported (#99). OrdinalPosition.LAST.to_n() returns -1, where it used to raise KeyError (#99).

Go: github.com/simpllyf/hron/go/v2

  • The module path is now github.com/simpllyf/hron/go/v2. Released v1 versions stay available under their old path (#94).
  • Parse, Display, FromCron, ToCron and Tokenize, which took or returned raw ScheduleData, are no longer exported. Use ParseSchedule, String(), FromCronExpr and Schedule.ToCron (#99).
  • NewSchedule checks every part with the same rules as parsing and copies it deeply. A bad part fails with an eval error, and a bad timezone, which used to be a parse error, is one of them (#99).
  • Data() returns a copy (#99).
  • ScheduleData.Expr is now Expression, and Anchor is now Starting (#101).
  • Token, TokenKind and the Token* constants are no longer exported (#101).
  • The package-level Occurrences and Between functions are no longer exported. The methods remain (#101).
  • HronError.Span counts Unicode code points, not bytes. It keeps its type, so code that slices the input with it must convert. The README shows how (#96).

Also new: the getter methods Expression(), Except(), Until(), Starting() and During(), which return copies, and Equal(other) (#101).

Java: io.hron:hron (Maven Central)

  • The parser, lexer, evaluator, cron and display packages move to io.hron.internal. A module-info exports only io.hron and the read-only io.hron.ast (#99).
  • ScheduleData.of and the with* methods are removed (#99).
  • Schedule.data() is removed (#101).
  • ScheduleData has moved to an in...
Read more

v1.0.0

Choose a tag to compare

@github-actions github-actions released this 20 Feb 19:20
Immutable release. Only release title and notes can be modified.
68484d2

What's Changed

Full Changelog: v0.6.1...v1.0.0

v0.6.1

Choose a tag to compare

@github-actions github-actions released this 16 Feb 22:01
Immutable release. Only release title and notes can be modified.
da749fc

What's Changed

  • feat: implement comprehensive from_cron support with full cron parity by @prasrvenkat in #54
  • feat: implement nearest weekday (W) support across all languages by @prasrvenkat in #55
  • feat: implement occurrences and between iterator API by @prasrvenkat in #56
  • feat: implement previousFrom() across all language bindings by @prasrvenkat in #57
  • chore: audit fixes, dynamic section discovery, and documentation by @prasrvenkat in #58
  • test: expand conformance suite with datetime edge case tests by @prasrvenkat in #59
  • fix: validate ISO dates semantically at parse time by @prasrvenkat in #60
  • fix: eliminate silent timezone error swallowing in Go eval by @prasrvenkat in #61
  • chore: add setup/format/lint just recipes and use them in CI by @prasrvenkat in #62
  • refactor!: fold OrdinalRepeat into MonthRepeat by @prasrvenkat in #63
  • fix: add explicit errors for unhandled variants in display modules by @prasrvenkat in #64
  • fix: validate parser inputs and improve eval safety across all implementations by @prasrvenkat in #65
  • release: v0.6.0 by @prasrvenkat in #66
  • fix: escape HTML entities in Javadoc comment by @prasrvenkat in #67
  • fix: fix javadoc warnings and remove unnecessary --enable-preview by @prasrvenkat in #68
  • release: v0.6.1 by @prasrvenkat in #69

Full Changelog: v0.6.0...v0.6.1

v0.5.1

Choose a tag to compare

@github-actions github-actions released this 14 Feb 00:02
Immutable release. Only release title and notes can be modified.
1e69441

What's Changed

Full Changelog: v0.4.2...v0.5.1

v0.4.2

Choose a tag to compare

@github-actions github-actions released this 12 Feb 20:30
Immutable release. Only release title and notes can be modified.
4110554

What's Changed

Full Changelog: v0.4.1...v0.4.2

v0.4.1

Choose a tag to compare

@github-actions github-actions released this 09 Feb 22:41
Immutable release. Only release title and notes can be modified.
ab16389

What's Changed

Full Changelog: v0.4.0...v0.4.1

v0.4.0

Choose a tag to compare

@github-actions github-actions released this 09 Feb 21:36
Immutable release. Only release title and notes can be modified.
e7c84b3

What's Changed

** BREAKING CHANGES **

Full Changelog: v0.3.2...v0.4.0

v0.3.2

Choose a tag to compare

@github-actions github-actions released this 09 Feb 08:20
Immutable release. Only release title and notes can be modified.
3e986ba

What's Changed

** BREAKING CHANGES **

  • feat: add interval support for day/month/ordinal/year repeats by @prasrvenkat in #16
  • feat!: cross-language API conformance & WASM tests by @prasrvenkat in #18
  • fix(ci): make release workflow publish reliably by @prasrvenkat in #20
  • fix(ci): remove setup-node to fix npm OIDC trusted publishing by @prasrvenkat in #22

Full Changelog: v0.1.2...v0.3.2

v0.1.2

Choose a tag to compare

@github-actions github-actions released this 08 Feb 21:38
Immutable release. Only release title and notes can be modified.
045abc6

What's Changed

Full Changelog: v0.1.1...v0.1.2

v0.1.1

Choose a tag to compare

@github-actions github-actions released this 08 Feb 21:18
Immutable release. Only release title and notes can be modified.
6e16ddf

What's Changed

Full Changelog: v0.1.0...v0.1.1