Skip to content

Allow int input when using a formatstring in into datetime#13541

Merged
fdncred merged 2 commits intonushell:mainfrom
NotTheDr01ds:int-to-dateformat
Aug 6, 2024
Merged

Allow int input when using a formatstring in into datetime#13541
fdncred merged 2 commits intonushell:mainfrom
NotTheDr01ds:int-to-dateformat

Conversation

@NotTheDr01ds
Copy link
Copy Markdown
Contributor

@NotTheDr01ds NotTheDr01ds commented Aug 5, 2024

Description

When using a format string, into datetime would disallow an int even when it logically made sense. This was mainly a problem when attempting to convert a Unix epoch to Nushell datetime. Unix epochs are often stored or returned as int in external data sources.

1722821463 | into datetime -f '%s'
Error: nu::shell::only_supports_this_input_type

  × Input type not supported.
   ╭─[entry #3:1:1]
 11722821463 | into datetime -f '%s'
   · ─────┬────   ──────┬──────
   ·      │             ╰── only string input data is supported
   ·      ╰── input type: int
   ╰────

While the solution was simply to | to text the int, this PR handles the use-case automatically.

Essentially a ~5 line change that just moves the current parsing to a closure that is called for both Strings and Ints-converted-to-Strings.

User-Facing Changes

After the change:

[
  1722821463
  "1722821463"
  0
] | each { into datetime -f '%s' }
╭───┬──────────────╮
│ 010 hours ago │
│ 110 hours ago │
│ 254 years ago │
╰───┴──────────────╯

Tests + Formatting

Test case added.

  • 🟢 toolkit fmt
  • 🟢 toolkit clippy
  • 🟢 toolkit test
  • 🟢 toolkit test stdlib

After Submitting

@NotTheDr01ds NotTheDr01ds marked this pull request as draft August 5, 2024 12:04
@fdncred
Copy link
Copy Markdown
Contributor

fdncred commented Aug 5, 2024

seems reasonable to me

@NotTheDr01ds NotTheDr01ds marked this pull request as ready for review August 5, 2024 18:34
@NotTheDr01ds
Copy link
Copy Markdown
Contributor Author

Thanks! Should be ready now with a test case in place.

@fdncred
Copy link
Copy Markdown
Contributor

fdncred commented Aug 5, 2024

Thinking a bit more about this I'm wondering if this is right. Should we be converting an int to a string? You can clearly do date now | into int | into datetime and it works fine. You can also do 1722821463 * 1_000_000_000 | into datetime and it works fine because nushell wants int time stamps to be in nanoseconds. The question is, why does -f %s require a string?

@NotTheDr01ds
Copy link
Copy Markdown
Contributor Author

NotTheDr01ds commented Aug 6, 2024

Thinking a bit more about this I'm wondering if this is right. Should we be converting an int to a string? You can clearly do date now | into int | into datetime and it works fine.

Sure, the user can multiply the Unix epoch by 1_000_000_000 as well, but | to text is slightly more concise and readable to me. Three options:

> let times = [
    1722821463
    1722821584
    1722821588
  ]

# Option 1 - Unwieldy because of the multiplication/conversion
> $times | each { $in * 1_000_000_000 | into datetime }

# Option 2 - Works, just slightly more verbose
> $times | each { to text | into datetime -f '%s' }

# Option 3 (this PR)
> $times | each { into datetime -f '%s' }

In the last two cases, either way, it gets converted to a string. Either internally with this PR or manually by the user with | to text. Given that Unix epochs are so commonly stored as ints in dbs and APIs, it seems like a natural conversion to handle for the user.

You can also do 1722821463 * 1_000_000_000 | into datetime and it works fine because nushell wants int time stamps to be in nanoseconds.

Yup - Exactly. into datetime already handles int input when accepting a Nushell datetime in nanoseconds.

But if you want to specify a format string to do seconds (Unix epoch) instead of nanoseconds (without this PR) you get a (to me) unexpected refusal.

The question is, why does -f %s require a string?

Well, I don't have to convert to string internally. I could write a new match arm using from_timestamp, but that seems like it would be a waste when the existing match can just take the val.into_string() and re-use the same closure for both match arms.

The conversion here is just a DRY tool.

@fdncred
Copy link
Copy Markdown
Contributor

fdncred commented Aug 6, 2024

Right - Either way, it gets converted to a string here. Either internally with this PR or manually by the user with | to text. Given that Unix epochs are so commonly stored as ints in dbs and APIs, it seems like a natural conversion to handle for the user.

I don't understand what you mean here. date now | into int | into datetime isn't converted to a string anywhere, it's a date, then int, then date.

I've fine with your other answers but was confused by the above statement.

@NotTheDr01ds
Copy link
Copy Markdown
Contributor Author

NotTheDr01ds commented Aug 6, 2024

I've fine with your other answers but was confused by the above statement.

Yeah, apologies - I misread your example at first - I've edited the above based on what you actually said.

@NotTheDr01ds
Copy link
Copy Markdown
Contributor Author

it's a date, then int, then date.

But using nanoseconds. To use an epoch, the int still requires some form of conversion.

@fdncred fdncred merged commit 4e83ccd into nushell:main Aug 6, 2024
@fdncred
Copy link
Copy Markdown
Contributor

fdncred commented Aug 6, 2024

thanks

@hustcer hustcer added this to the v0.97.0 milestone Aug 6, 2024
@NotTheDr01ds NotTheDr01ds deleted the int-to-dateformat branch August 6, 2024 02:19
@fdncred fdncred added the deprecated:pr-commands (deprecated: too vague) This PR changes our commands in some way label Aug 6, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

deprecated:pr-commands (deprecated: too vague) This PR changes our commands in some way

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants