Skip to content

Split instant() to two simpler functions instant() and instantFromText()#69

Merged
rockorager merged 3 commits into
rockorager:mainfrom
AloisMahdal:instant_split
May 19, 2026
Merged

Split instant() to two simpler functions instant() and instantFromText()#69
rockorager merged 3 commits into
rockorager:mainfrom
AloisMahdal:instant_split

Conversation

@AloisMahdal

@AloisMahdal AloisMahdal commented May 17, 2026

Copy link
Copy Markdown
Contributor

Current signature of zeit.instant() is:

fn instant(io: std.Io, config: Instant.Config) !Instant;

which forces unnecessary complexity at call site, because:

  • it's fallible (!Instant), but the fallibility is only applicable when parsing text, ie. when config.source is initialized with certain tags,

  • and it always accepts std.Io but this is only relevant when config.source is initialized with .now tag.

This commit splits current .instant() into two simpler functions:

fn instant(source: Instant.Source, tz: *const TimeZone) Instant;

where accepted union contains std.Io only when necessary, ie. as payload for the .now tag, and

fn instantFromText(format: Instant.TextFormat, text: []const u8, tz: *const TimeZone) !Instant;

where TextFormat enum contains only recognized formats (eg. .iso8601).

Notice that in the first case, even though .instant() can talk to std.Io, the call is to system clock, which is infallible.

Also I've "smuggled in" further simplification: timezone information is passed as separate argument, instead of Instant.Config, leading to more readable call sites in both cases, as demonstrated in README.md and tests:

const now = try zeit.instant(io, .{});

⬇️

const now = zeit.instant(.{.now = io}, &zeit.utc);

..

const epoch = try zeit.instant(std.testing.io, .{ .source = .{ .unix_timestamp = 0 } });

⬇️

const epoch = zeit.instant(.{ .unix_timestamp = 0 }, &zeit.utc);

and

_ = try zeit.instant(std.testing.io, .{
    .source = .{
        .rfc3339 = "2024-03-16T08:38:29.496706064-1200",
    },
});

⬇️

_ = try zeit.instantFromText(
    .rfc3339,
    "2024-03-16T08:38:29.496706064-1200",
    &zeit.utc,
);

The readability comes at a small price that timezone, which would default to UTC in the older API, now must be passed, but this is trivial, easy to learn from the README.md and arguably better as in "more explicit".

@AloisMahdal

Copy link
Copy Markdown
Contributor Author

Note that while looking for call sites and docs to update, I found some under the .latch sub-directory but I have no idea what it is and it seemed irrelevant so I did not touch it.

Current signature of zeit.instant() is:

    fn instant(io: std.Io, config: Instant.Config) !Instant;

which forces unnecessary complexity at call site, because:

 *  it's fallible (`!Instant`), but the fallibility is only applicable
    when parsing text, ie. when config.source is initialized with
    certain tags,

 *  and it always accepts std.Io but this is only relevant when
    config.source is initialized with `.now` tag.

This commit splits current .instant() into two simpler functions:

    fn instant(source: Instant.Source, tz: *const TimeZone) Instant;

where accepted union contains `std.Io` only when necessary, ie. as
payload for the `.now` tag, and

    fn instantFromText(format: Instant.TextFormat, text: []const u8, tz: *const TimeZone) !Instant;

where *TextFormat* enum contains only recognized formats (eg.
`.iso8601`).

Notice that in the first case, even though .instant() can talk to
std.Io, the call is to system clock, which is infallible.

Also I've "smuggled in" further simplification: timezone information is
passed as separate argument, instead of `Instant.Config`, leading to
more readable call sites in both cases, as demonstrated in README.md
and tests:

    const now = try zeit.instant(io, .{});

⬇️

    const now = zeit.instant(.{.now = io}, &zeit.utc);

..

    const epoch = try zeit.instant(std.testing.io, .{ .source = .{ .unix_timestamp = 0 } });

⬇️

    const epoch = zeit.instant(.{ .unix_timestamp = 0 }, &zeit.utc);

and

    _ = try zeit.instant(std.testing.io, .{
        .source = .{
            .rfc3339 = "2024-03-16T08:38:29.496706064-1200",
        },
    });

⬇️

    _ = try zeit.instantFromText(
        .rfc3339,
        "2024-03-16T08:38:29.496706064-1200",
        &zeit.utc,
    );

The readability comes at a small price that timezone, which would
default to UTC in the older API, now *must* be passed, but this is
trivial, easy to learn from the README.md and arguably better as in
"more explicit".
@AloisMahdal AloisMahdal changed the title Split zeit.instant() to two simpler functions .instant() and .instantFromText() Split instant() to two simpler functions instant() and instantFromText() May 17, 2026
@AloisMahdal

Copy link
Copy Markdown
Contributor Author

(force-pushing to remove period prefixes from the commit message---added by me out of weird habit.)

@rockorager rockorager merged commit 0ad98cc into rockorager:main May 19, 2026
4 checks passed
@AloisMahdal AloisMahdal deleted the instant_split branch May 22, 2026 22:47
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

Successfully merging this pull request may close these issues.

2 participants